2016-08-07 4 views
10

時々、セミコロン ';'で始まるSQL Server文があります。まさにそこにあるのはなぜ';' TSQL文の冒頭で

;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 

以下のような他の例では、;THROW

は 'は;' TSQL文の先頭

アップデート1:

私が求めていますので注意してください ';'ステートメントの冒頭に。この質問は、この1

When should I use semicolons in SQL Server?

の複製されていないアップデート2:

@MartinSmithの答えは、理にかなっています。

だけで、私たちはこの記事のために完全な答えを持っていることを確認し、この尊敬の記事を検討するために:あなたは自分自身に言っているかもしれません。この時点で

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

を:彼は私の の足を引っ張っする必要があります、Microsoftは実際にコマンドを呼び出しましたか? スルー? True、Books Onlineで検索すると、先頭に セミコロンはありません。しかしセミコロンはそこになければなりません。正式には、前のステートメントの終端文字は ですが、オプションです.は誰でもセミコロンを使用してT-SQLステートメントを終了します。

私は@MartinSmithの答えに同意しますが、それは非常に極端なレベルに陥っているようです。

通常、ストアドプロシージャTHROWは、独自の行によるステートメントです。 SQL開発者は、単にそのようなSQL行をマージするだけでなく、セミコロンを見逃してしまいます。

私には、人々が誤ってTSQL

の別の行に「THROW」ステートメントを混合よりも、テーブルをドロップより多くのチャンスがあり起こり、極端な珍しい何か上記の引用で説明したケースですか?または私はここでポイントを逃している?

答えて

13

前のステートメント以外のステートメントの後にあるはずです。しかし、TSQLのほとんどの場合、実際にはステートメントの終了セミコロンはオプションですが(技術的にはNot ending Transact-SQL statements with a semicolonは非推奨です)、セミコロンを終了するステートメントの存在は強制されません。

例外は、だから、このようなケースではStackOverflowの上で答えをやや守備の練習OP(または将来の読者)である(つまり、終了セミコロンを必要としません)MERGEの文であり、またWITHまたはTHROW

の前の文前のステートメントで必要なセミコロンを持たない既存のバッチの中央に貼り付けて、それが機能しないと訴え、次のエラーを受け取ります。

「with」というキーワードの構文が正しくありません。このステートメントが 共通テーブル式、xmlnamespaces句、または変更トラッキング コンテキスト句である場合、前のステートメントはセミコロン で終了する必要があります。この文は、追加1の問題はありませんセミコロンで終了しある場合には

。空の文として扱われます。

複数のステートメントが有効でないコンテキストでCTEが使用される場所でも、この慣習自体が問題を引き起こす可能性があります。例えばWITHの前にセミコロンを挿入すると、それが壊れてしまいます。

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

THROW同様に先頭のセミコロンを挿入すると、問題が発生する可能性があります。

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

付近に正しくない構文 ';'。

私はthe example you give in your questionを固定し、それが、これはパーサにコードが行うことになっているかを把握するために戦うチャンスを与えることについてだと思う

; 

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

ありがとうございました。私の更新されたコメントにあなたを共有することができるでしょうか? –

+0

@AllanXu - はい私はあなたの感情に ';スルー"の意見に同意します - この練習は私がウェブ上のコードサンプルについて考えているものです。私自身のソースコードではありません。正しいことは、前述のステートメント(および理想的にはすべてのステートメント)をセミコロンで終了させることです。 –

2

にそれを変更しました。

throwは予約語ではなく、withは他の文の一部として使用できます。 Transact-SQLで

完全に有効な文:

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

注意改行は、パーサは別の1文を分離するために使用するものではありませんことを。

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

これはあなたが本当にこれを意味していることを理解するために、他の種類の魔法を使用します。だから、

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

insert into throw values(1); 

select * 
from throw; 

、CTEのは、SQL Server 2005で導入されたとスローは、SQL Server 2012で追加されたとき、前の文は文の終了で終了していることを要求されたときに、物事を容易にします。

マージステートメントの最後に;が必要なのと同じ理由があります。

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); 

コードを解析して、実際に文がどこで終了するかを簡単に確認できます。

関連する問題