it-swarm.com.de

SQL "IF", "BEGIN", "END", "END IF"?

Überhaupt keine SQL-Person. Habe folgenden Code von einem Berater geschrieben.

Zuerst wird sichergestellt, dass nur eine Grundschule ausgewählt wurde. Wenn nach BEGIN die Variable @Term gleich 3 ist, möchten wir die Aufgaben unter dieser IF-Anweisung ausführen. Hier ist das Problem. Wenn @Term nicht = 3 ist, möchten wir trotzdem den Teil SECOND INSERT INTO @Classes ausführen. FYI - der Term ist = 3, wenn dies ausgeführt wird, aber es werden nicht beide INSERTs ausgeführt - sollte am Ende dieses Abschnitts "IF @Term = 3" ein END IF stehen, anstatt nur ein einfaches 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
38
Melissa

Es hat mit der Normalform für die SQL-Sprache zu tun. IF -Anweisungen können per Definition nur eine einzelne SQL-Anweisung annehmen. Es gibt jedoch eine spezielle Art von SQL-Anweisungen, die mehrere SQL-Anweisungen enthalten können, nämlich den Block BEGIN-END.

Wenn Sie den BEGIN-END - Block weglassen, wird Ihr SQL-Code ordnungsgemäß ausgeführt, es wird jedoch nur die erste Anweisung als Teil des IF ausgeführt.

Grundsätzlich ist dies:

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

ist gleichbedeutend mit dem Block BEGIN-END, da Sie nur eine einzige Anweisung ausführen. Aus dem gleichen Grund ist die Verwendung von immer vorzuziehen, da die geschweiften Klammern in einer IF -Anweisung in einer C-ähnlichen Sprache nicht enthalten sind BEGIN und END.

45
foxxtrot

In SQL gibt es kein ENDIF.

Die Anweisung, die direkt auf ein IF folgt, wird nur ausgeführt, wenn der if-Ausdruck wahr ist.

Das BEGIN ... END-Konstrukt ist vom IF getrennt. Es bindet mehrere Anweisungen zu einem Block zusammen, der so behandelt werden kann, als ob es sich um eine einzelne Anweisung handelt. Daher kann BEGIN ... END direkt nach einem IF verwendet werden, und somit wird der gesamte Codeblock in der BEGIN .... END-Sequenz entweder ausgeführt oder übersprungen.

In deinem Fall vermute ich, dass das "(more code)" nach FROM XXXXX dein Problem ist.

24
AnthonyWJones

Aus der Hand sieht der Code richtig aus. Was ist, wenn Sie versuchen, ein "Else" zu verwenden und sehen, was passiert?

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
9
SquidScareMe

Wenn es sich um MS SQL Server handelt, sollte das, was Sie haben, einwandfrei funktionieren. Technisch gesehen brauchen Sie das Begin & End überhaupt nicht, da es nur eine Anweisung im begin-End Block gibt @Classes ist eine Tabellenvariable?)

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)
3
Charles Bretana

Sie können den Code auch neu schreiben, um die verschachtelte 'If'-Anweisung vollständig zu entfernen.

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) 
2
user25623

Wenn ich mich richtig erinnere und öfter nicht, gibt es in Transact-Sql keine Unterstützung für END IF. BEGIN und END sollten den Job erledigen. Erhalten Sie Fehler?

1
mattruma

Die zweite Einfügung in @clases sollte nur dann fehlschlagen, wenn in der ersten Einfügungsanweisung ein Fehler aufgetreten ist.

Wenn dies der Fall ist, müssen Sie entscheiden, ob die zweite Anweisung vor der ersten ausgeführt werden soll OR wenn Sie eine Transaktion benötigen, um ein Rollback durchzuführen.

1
NotMe

Basierend auf Ihrer Beschreibung, was Sie tun möchten, scheint der Code so zu sein, wie er ist. ENDIF ist kein gültiges Schlüsselwort für die SQL-Schleifensteuerung. Sind Sie sicher, dass die INSERTS tatsächlich Daten abrufen, die in @Classes abgelegt werden sollen? In der Tat, wenn es schlecht wäre, würde es einfach nicht laufen.

Was Sie vielleicht versuchen möchten, ist, ein paar PRINT-Anweisungen einzutragen. Platzieren Sie einen PRINT über jedem der INSERTS und geben Sie nur einen albernen Text aus, um anzuzeigen, dass diese Zeile ausgeführt wird. Wenn Sie beide Ausgänge erhalten, ist Ihr SELECT ... INSERT ... verdächtig. Sie können auch einfach SELECT anstelle von PRINT ausführen (d. H. Ohne INSERT) und genau sehen, welche Daten abgerufen werden.

0
Michael Bray