Warum sollte ein CTE mit einem Semikolon beginnen?


13

Ich habe mir gerade einen Beitrag zu StackOverflow angesehen, in dem Aaron Bertrand vorschlägt, einen CTE anstelle einer Nummerntabelle zu verwenden, was eine elegante Möglichkeit darstellt, die anstehende Aufgabe auszuführen. Meine Frage ist, warum die erste Zeile des WAK mit einem Semikolon beginnt.

;WITH n AS (SELECT TOP (10000) n FROM 
  (SELECT n = ROW_NUMBER() OVER
    (ORDER BY s1.[object_id])
    FROM sys.all_objects AS s1
    CROSS JOIN sys.all_objects AS s2
  ) AS x ORDER BY n
)
SELECT n FROM n ORDER BY n; -- look ma, no gaps!

Soll dies sicherstellen, dass die WITH-Anweisung nicht in eine frühere SELECToder eine andere Anweisung zerlegt wird ? Ich sehe in SQL Server 2005 BOL nichts über die Verwendung eines Semikolons vor dem WITH.


Antworten:


25

Ich mache das immer, wenn ich hier oder auf StackOverflow poste, weil WITHder vorherige Befehl - da das Schlüsselwort überladen ist - ein abschließendes Semikolon erfordert. Wenn ich ein Codebeispiel einfüge, das einen CTE verwendet, wird dieser zwangsläufig von einigen Benutzern in den vorhandenen Code eingefügt, und die vorherige Anweisung enthält kein Semikolon. Der Code bricht also und ich bekomme Beschwerden wie:

Ihr Code ist kaputt gegangen! Ich habe folgende Fehlermeldung erhalten:

Incorrect syntax near 'WITH'...

Während ich glauben möchte, dass die Leute besser werden , wenn sie ihre Aussagen immer mit einem Semikolon abschließen , würde ich das Rauschen lieber vorwegnehmen und es einfach immer mit einbeziehen. Manche Leute mögen es nicht, aber <shrug />. Sie können beliebig viele Semikolons vor oder nach einer gültigen Anweisung einfügen. Das ist gültig:

;;;;SELECT 1;;;;;;;;;;;;SELECT 2;;;;;;;;SELECT 3;;;;;

Es schadet also nichts, wenn ein zusätzliches Semikolon vor einer Anweisung steht, die dies per Definition erfordert. Das ist sicherer, auch wenn es nicht so hübsch ist.

Es muss seltsam formuliert werden, um den Punkt zu verdeutlichen, aber "eine gültige Anweisung nicht mit einem Semikolon zu beenden" ist seit SQL Server 2008 veraltet. Wie ich im Blog-Post beschreibe, verweise ich auf den obigen Link, auch in Fällen, in denen Es ist nicht erforderlich, einen Fehler zu umgehen. Es sollte verwendet werden, wo immer dies gültig ist. Sie können dies hier sehen:

http://msdn.microsoft.com/en-us/library/ms143729.aspx

(Suche auf der letzten Seite nach "Semikolon")

Natürlich wäre es nicht SQL Server, wenn es keine Ausnahmen gäbe. Versuche dies:

BEGIN TRY;
  SELECT 1/1;
END TRY;
BEGIN CATCH;
  SELECT 1/1;
END CATCH;

Es ist nicht die einzige Ausnahme von der Regel, aber die, die ich am wenigsten intuitiv finde.


1
Im Jahr 2012 erhalte ich sogar die gleiche Fehlermeldung, allerdings nur wegen des Semikolons nach END TRY: i.stack.imgur.com/rc6dw.png - wenn ich dieses Semikolon entferne, funktioniert alles.
Aaron Bertrand

Ich denke, Sie können ein Semikolon nicht BEGIN CATCHeinfach vorher setzen , weil es Teil einer einzelnen zusammengesetzten Anweisung ist, die mit eingeführt wird BEGIN TRY. Es ist dasselbe wie ein Semikolon vor eine IFAnweisung zu setzen ELSE.
Andriy M

@AndriyM Ich war in ein viel ausführlicheres Gespräch über die Regeln hier eingeweiht. Ich habe es erwähnt, weil es eine Überraschung für alle ist, die darauf stoßen, und nicht, weil ich den Grund nicht verstehe. :-)
Aaron Bertrand

10

Dies soll sicherstellen, dass es nicht in vorherigen Anweisungen enthalten ist, da es WITHin T-SQL eine Vielzahl von Zwecken erfüllen kann.

Wenn es die erste Aussage im Stapel ist, denke ich nicht, dass Sie es brauchen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.