2016-08-07 19 views
10

Von Zeit zu Zeit sehe ich SQL Server-Anweisungen, die mit Semikolon ';' wie unten';' am Anfang von TSQL-Anweisungen

;WITH cte 
    AS (SELECT ROW_NUMBER() OVER (PARTITION BY Col1, Col2, Col3 
             ORDER BY (SELECT 0)) RN 
     FROM #MyTable) 
DELETE FROM cte 
WHERE RN > 1 

Das andere Beispiel ;THROW

ist Warum genau es ist ein ';' Anfang TSQL Aussagen

Update 1:

Bitte beachten Sie, dass ich mich fragen, ';' am Anfang der Aussagen. Diese Frage ist nicht duplizieren diese eine

When should I use semicolons in SQL Server?

Update 2:

@MartinSmith Antwort macht Sinn.

Nur um sicherzustellen, dass wir eine vollständige Antwort für diesen Beitrag haben, betrachten Sie dieses angesehenen Artikel:

http://www.sommarskog.se/error_handling/Part1.html#jumpTHROW

An diesem Punkt, den Sie selbst sagen könnte: er muss meine Beine Strang ziehen , hat Microsoft wirklich den Befehl aufgerufen, THROW? Ist es nicht nur THROW? Richtig, wenn Sie in der Onlinedokumentation nachschlagen, gibt es kein führendes Semikolon . Aber das Semikolon muss da sein. Offiziell ist es ein Terminator für die vorherige Anweisung, aber es ist optional, und weit von jedem verwendet Semikolons, um ihre T-SQL-Anweisungen zu beenden.

Ich stimme @MartinSmith Antwort, aber es scheint, dass die Angelegenheit auf einige ziemlich extreme Ebenen genommen wird.

In der Regel ist THROW in einer gespeicherten Prozedur eine Anweisung der eigenen Zeile. SQL-Entwickler verschmelzen einfach nicht einfach SQL-Zeilen und verpassen ein Semikolon.

Für mich gibt es mehr Chancen, Menschen aus Versehen einen Tisch fallen als ‚THROW‘ Aussage mit einer anderen Linie von TSQL Misch

ist der Fall erklärt in dem Zitat oben etwas extremer und selten zu geschehen? oder ich verpasse hier einen Punkt?

Antwort

13

Es soll nach den Aussagen nicht vor ihnen liegen. In den meisten Fällen sind in TSQL die abschließenden Semikolons für Anweisungen in der Praxis jedoch optional (obwohl technisch Not ending Transact-SQL statements with a semicolon veraltet ist) und das Vorhandensein von Semikolons, die die Anweisung beenden, wird nicht erzwungen.

Eine Ausnahme ist die MERGE Anweisung (das einen Abschluss Semikolon erforderlich ist) und auch Aussagen vorhergehenden WITH oder THROW

Das ist also eine etwas defensive Praxis Antworten auf Stackoverflow bei der OP (oder zukünftigen Lesern) fügt es in die Mitte eines vorhandenen Stapels ein, das nicht den erforderlichen Semikolon der vorherigen Anweisung enthält, und klagt dann, dass es nicht funktioniert und sie den folgenden Fehler erhalten.

Falsche Syntax in der Nähe des Schlüsselwortes 'mit'. Wenn es sich bei dieser Anweisung um einen gemeinsamen Tabellenausdruck , eine XMLNamespaces-Klausel oder eine Conversion-Klausel für die Änderungsverfolgung handelt, muss die vorherige Anweisung mit einem Semikolon abgeschlossen werden.

Im Fall, dass die vorhergehende Anweisung mit einem Semikolon des zusätzlich man keinen Schaden anrichtet beendet ist. Es wird nur als leere Anweisung behandelt.

Diese Vorgehensweise kann jedoch selbst Probleme verursachen, wenn das CTE in einem Kontext verwendet wird, in dem Mehrfachanweisungen nicht gültig sind. z.B. Das Einfügen eines Semikolons vor dem WITH hier würde es brechen.

CREATE VIEW V1 
AS 
    WITH T(X) 
     AS (SELECT 1) 
    SELECT * 
    FROM T; 

Ebenso für THROW blind eine führende Semikolon Einfügen kann Probleme verursachen.

IF @i IS NULL 
;THROW 50000, '@i IS NULL', 1; 

falsche Syntax nahe ';'.

Ich habe the example you give in your question festgelegt und geändert, es zu

; 

--Ensure that any immediately preceding statement is terminated with a semicolon above 
WITH cte 
    AS (SELECT ROW_NUMBER() OVER (PARTITION BY Col1, Col2, Col3 
             ORDER BY (SELECT 0)) RN 
     FROM #MyTable) 
DELETE FROM cte 
WHERE RN > 1; 
+0

Vielen Dank für Hilfe hier. Können Sie Ihre Kommentare zu meinen aktualisierten Kommentaren teilen? –

+0

@AllanXu - Ja, ich stimme deinen Gefühlen zu '; THROW' zu - diese Vorgehensweise ist nur etwas, was ich für Code-Beispiele im Internet in Erwägung ziehen würde. Nicht etwas in meinem eigenen Quellcode. Als die richtige Sache zu tun ist nur, um sicherzustellen, dass Sie die vorhergehenden Aussagen (und im Idealfall alle Aussagen) mit Semikola beenden. –

2

Es denkt, das ist etwa der Parser eine Chance geben, um herauszufinden, was der Code tun soll.

throw ist kein reserviertes Schlüsselwort und with kann als Teil anderer Anweisungen verwendet werden.

Perfekt gültige Anweisung in Transact-SQL:

create table throw 
(
    ID int 
) 
with(data_compression = none) 

Beachten Sie, dass Zeilenumbrüche ist nicht etwas, was der Parser eine Anweisung von einem anderen zu trennen, verwendet.

create 
table 
throw(ID int) 
with (data_compression = none) insert into 
throw values(1) select 
* from throw 

Es benutzt eine andere Art von Magie, um herauszufinden, dass Sie das wirklich meinten.

create table throw(ID int) 
with (data_compression = none); 

insert into throw values(1); 

select * 
from throw; 

Also, um die Dinge einfacher, wenn CTE wurde in SQL Server 2005 eingeführt und wenn throw in SQL Server 2012 hinzugefügt wurde, ist es erforderlich, dass die vorhergehende Anweisung mit einer Erklärung Terminator beendet.

Gleicher Grund für die Anforderung einer ; am Ende einer Merge-Anweisung.

declare @T table(ID int, Value int); 

merge into @T as T 
using (values(1, 100)) as S(ID, Value) 
on T.ID = S.ID 
when matched then 
    update set Value = S.Value 
when not matched then 
    insert (ID, Value) values(S.ID, S.Value); 

Leichter zu analysieren den Code und sehen, wo die Anweisung tatsächlich endet.

Verwandte Themen