2008-12-31 15 views
31

No es una persona SQL en absoluto. Tenga el siguiente código escrito por un consultor.SQL "IF", "BEGIN", "END", "END IF"?

En primer lugar, se asegura de que solo se haya elegido una escuela primaria; luego, después del COMIENZO, si la variable @Term es igual a un 3, queremos hacer las cosas bajo esa declaración IF. Este es el problema. Cuando @Term no es = 3, aún queremos desplegar y hacer la SEGUNDA INSERTACIÓN en la parte @Classes. FYI - el Término es = 3 cuando esto se está ejecutando, pero no está haciendo los dos INSERTES - ¿debería haber un IF FINAL al final de esa sección "IF @Term = 3" en lugar de simplemente END?

IF @SchoolCategoryCode = 'Elem' 

--- We now have determined we are processing an elementary school... 

BEGIN 

---- Only do the following if the variable @Term equals a 3 - if it does not, skip just this first part 

    IF @Term = 3 

    BEGIN 

     INSERT INTO @Classes 

     SELECT  
     XXXXXX 
     FROM XXXX blah blah blah 

    END <----(Should this be ENDIF?) 

---- **always** "fall thru" to here, no matter what @Term is equal to - always do the following INSERT for all elementary schools 

    INSERT INTO @Classes  
    SELECT 
    XXXXXXXX  
    FROM XXXXXX (more code) 

END 
+0

I sangría del código dentro del bloque más interno Begin-End, pensé que podría ayudar a algunos. – MrBoJangles

Respuesta

2

Si esto es MS SQL Server a continuación, lo que tiene debería funcionar bien ... De hecho, técnicamente, Don; t necesidad Begin & final del todo, SNCE sólo hay una declaración en el COMIENZO final de bloque ... (supongo @Classes es una variable de tabla?)

If @Term = 3 
    INSERT INTO @Classes 
    SELECT     XXXXXX 
    FROM XXXX blah blah blah 
-- ----------------------------- 

-- This next should always run, if the first code did not throw an exception... 
INSERT INTO @Classes  
SELECT XXXXXXXX   
FROM XXXXXX (more code) 
0

Si no recuerdo mal, y más a menudo entonces no lo haga ... no hay END IF apoyo en Transact-SQL. BEGIN y END deberían hacer el trabajo. ¿Estás recibiendo errores?

0

Según su descripción de lo que quiere hacer, el código parece ser correcto. ENDIF no es una palabra clave de control de bucle SQL válida. ¿Estás seguro de que los INSERTS realmente están extrayendo datos para ponerlos en @Classes? De hecho, si era malo, simplemente no funcionaría.

Lo que podría querer probar es poner algunas declaraciones PRINT allí. Coloque una IMPRESIÓN sobre cada uno de los INSERTS que acaban de enviar un texto tonto para mostrar que esa línea se está ejecutando. Si obtienes ambas salidas, entonces tu SELECCIONAR ... INSERTAR ... es sospechoso. También puede hacer SELECCIONAR en lugar de IMPRIMIR (es decir, sin INSERTAR) y ver exactamente qué datos se están extrayendo.

18

No hay ENDIF en SQL.

La instrucción directamente seguida de un IF se ejecuta solo cuando la expresión if es verdadera.

El constructo BEGIN ... END está separado del IF. Vincula varias instrucciones juntas como un bloque que puede tratarse como si fueran una sola declaración. Por lo tanto, BEGIN ... END se puede usar directamente después de un IF y, por lo tanto, todo el bloque de código en la secuencia BEGIN .... END se ejecutará o saltará.

En su caso, sospecho que el "(más código)" que sigue DE XXXXX es donde está su problema.

29

Tiene que ver con la forma normal para el lenguaje SQL. Las sentencias IF pueden, por definición, solo tomar una declaración SQL única. Sin embargo, existe un tipo especial de instrucción SQL que puede contener varias instrucciones SQL, el bloque BEGIN-END.

Si omite el bloque begin-end, su SQL se ejecutará correctamente, pero solo ejecutará la primera instrucción como parte del IF.

Básicamente, esto:

IF @Term = 3 
    INSERT INTO @Classes 
    SELECT    
     XXXXXX 
    FROM XXXX blah blah blah 

es equivalente a la misma cosa con el bloque BEGIN-END, ya que sólo está ejecutando un solo estado. Sin embargo, por la misma razón que no incluir las llaves en una instrucción if en un lenguaje tipo C es una mala idea, es siempre preferible utilizar BEGIN y END.

+0

inmensamente útil. – VSO

4

Apagado el código parece correcto. ¿Qué pasa si intentas usar un 'Else' y ves qué pasa?

IF @SchoolCategoryCode = 'Elem' 

--- We now have determined we are processing an elementary school... 

BEGIN 

---- Only do the following if the variable @Term equals a 3 - if it does not, skip just this first part 

    IF @Term = 3 
    BEGIN 
     INSERT INTO @Classes 

     SELECT    
      XXXXXX 
     FROM XXXX blah blah blah 

     INSERT INTO @Classes  
     SELECT 
     XXXXXXXX  
     FROM XXXXXX (more code) 
    END <----(Should this be ENDIF?) 
    ELSE 
    BEGIN 


     INSERT INTO @Classes  
     SELECT 
     XXXXXXXX  
     FROM XXXXXX (more code) 
    END 
END 
+0

Yo de nuevo. No puedo agregar un "ELSE". Porque, siempre quiero hacer la declaración 2nd INSERT, ya sea que @Term = 3 –

1

La única vez que el segundo inserto en @clases debería fallar al iniciarse es si se produjo un error en la primera instrucción de inserción.

Si ese es el caso, entonces necesita decidir si la segunda declaración debe ejecutarse antes de la primera O si necesita una transacción para realizar una reversión.

2

También podría reescribir el código para eliminar por completo la instrucción anidada 'If'.

INSERT INTO @Classes  
SELECT XXXXXX  
FROM XXXX 
Where @Term = 3 

---- **always** "fall thru" to here, no matter what @Term is equal to - always do 
---- the following INSERT for all elementary schools  
INSERT INTO @Classes   
SELECT XXXXXXXX   
FROM XXXXXX (more code) 
+0

sea o no una buena idea. El siguiente paso lógico sería reducir esto a una inserción con una selección UNION ALL. –

-9

Francamente esto parece como algo que debe estar en la capa de aplicación, no la capa de base de datos ...

Cuestiones relacionadas