2008-12-31 10 views
31

Keine SQL-Person überhaupt. Habe folgenden Code einen Berater geschrieben.SQL "IF", "BEGIN", "END", "END IF"?

Zuerst stellt es sicher, dass nur eine Grundschule gewählt wurde - dann, nach dem BEGIN, wenn die Variable @Term gleich 3 ist, wollen wir die Sachen unter dieser IF-Anweisung machen. Hier ist das Problem. Wenn @Term nicht = 3 ist, möchten wir immer noch den zweiten Teil in den @Classes-Teil einfügen. FYI - der Term ist = 3, wenn er ausgeführt wird, aber es werden nicht beide INSERTs ausgeführt - sollte es am Ende dieses "IF @Term = 3" -Bereichs eine END IF geben 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 
+0

ich eingerückt den Code innerhalb des innersten Begin-End-Blockes, dachte es einige helfen könnte. – MrBoJangles

Antwort

2

Wenn dieser MS SQL Server ist dann, was Sie sollten arbeiten gut ... In der Tat, technisch, Sie don; t die & Ende überhaupt beginnen müssen, snce es in der BEGIN nur eine Anweisung ist End-Block ... (ich gehe davon aus @Classes eine Tabelle Variable ist?)

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

Wenn ich mich richtig erinnere, und öfter dann nicht ich ... es gibt keine END IF Unterstützung in Transact-SQL. Das BEGIN und das ENDE sollten die Aufgabe erledigen. Erhalten Sie Fehler?

0

Basierend auf Ihrer Beschreibung, was Sie tun möchten, scheint der Code korrekt zu sein. ENDIF ist kein gültiges SQL-Kontrollschlüsselwort. Sind Sie sicher, dass die INSERTS Daten in @Classes ziehen? In der Tat, wenn es schlecht war, würde es einfach nicht laufen.

Was Sie vielleicht versuchen möchten, ist, ein paar PRINT-Anweisungen dort zu setzen. Setzen Sie eine PRINT über jedem der Inserts nur etwas albernen Text auszugeben, um zu zeigen, dass diese Linie ausgeführt wird. Wenn Sie beide Ausgaben erhalten, ist Ihre SELECT ... INSERT ... verdächtig. Sie können auch SELECT anstelle von PRINT (dh ohne INSERT) verwenden und genau sehen, welche Daten gezogen werden.

18

Es gibt kein ENDIF in SQL.

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

Das BEGIN ... END-Konstrukt ist von der IF getrennt. Es bindet mehrere Anweisungen zusammen als einen Block, der so behandelt werden kann, als ob sie eine einzelne Anweisung wären. 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 Ihrem Fall vermute ich, dass die "(mehr Code)" folgende von XXXXX ist, wo Ihr Problem ist.

29

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-Anweisung, die mehrere SQL-Anweisungen enthalten kann, den BEGIN-END-Block.

Wenn Sie den Begin-End-Block weglassen, wird Ihr SQL-Befehl ordnungsgemäß ausgeführt, aber es wird nur die erste Anweisung als Teil des IF ausgeführt.

Im Grunde ist dies:

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

entsprechen die gleiche Sache mit dem Block BEGIN-END, da Sie nur sind eine einzige Anweisung ausgeführt wird. Aus demselben Grund, dass es nicht ratsam ist, geschweifte Klammern für eine if-Anweisung in einer C-ähnlichen Sprache zu verwenden, ist es immer vorzuziehen, BEGIN und END zu verwenden.

+0

Sehr hilfreich. – VSO

4

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

+0

Ich wieder. Ich kann kein "ELSE" hinzufügen. Weil ich immer die 2. INSERT-Anweisung machen möchte, ob @Term = 3 –

1

Das einzige Mal, wenn die zweite Einfügung in @clases fehlschlagen sollte, ist, wenn in der ersten Einfügeanweisung ein Fehler aufgetreten ist.

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

2

Sie könnten 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) 
+0

Gutes Denken. Der nächste logische Schritt wäre, dies auf eine Einfügung mit UNION ALL select zu reduzieren. –

-9

Ehrlich gesagt scheint dies etwas, das auf der Anwendungsschicht sein sollte, nicht die Datenbank ... Schicht

Verwandte Themen