web-dev-qa-db-ja.com

CTEがセミコロンで始まる必要があるのはなぜですか?

私はちょうど StackOverflow に関する投稿を見ていました。AaronBertrandは、数値表の代わりにCTEを使用することを提案しています。これは、目前のタスクを実行するためのエレガントな方法です。私の質問は、CTEの最初の行がセミコロンで始まるのはなぜですか?

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

これは、WITHステートメントが以前のSELECTなどに解析されないようにするためのものですか? SQL Server 2005 BOLでは、WITHの前にセミコロンを使用することについて何も見ていません。

15
Max Vernon

WITHの場合-キーワードがオーバーロードされているため-previousコマンドには終了セミ-結腸。 CTEを使用するコードサンプルを貼り付けると、必然的に一部のユーザーが既存のコードに貼り付けて、前のステートメントにセミコロンがなくなります。コードが壊れて、次のような不満が出ます。

コードが壊れました!私はこのエラーメッセージを受け取りました:

Incorrect syntax near 'WITH'...

私は 人々は常にセミコロンでステートメントを終了することについて良くなっています と信じたいのですが、むしろノイズを先取りし、常にそれを含めるだけです。気に入らない人もいますが、<shrug />。有効なステートメントの前後に必要なだけセミコロンを含めることができます。これは有効です:

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

したがって、定義上それを必要とするステートメントの前にセミコロンを追加しても問題はありません。それがそれほどきれいでなくても、そうする方が安全です。

要点を伝えるために奇妙な言い方をする必要がありますが、「有効なステートメントをセミコロンで終了しない」ことは、SQL Server 2008以降非推奨になっています。ブログの記事で説明しているように、エラーを回避する必要はありません。有効な場所で使用してください。あなたはここでこれを見ることができます:

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

(最後のページで「セミコロン」を検索してください)

もちろん、例外がなければSQL Serverにはなりません。これを試して:

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

それはルールの唯一の例外ではありませんが、私が最も直感的でないと思うものです。

26
Aaron Bertrand

これは、WITHがT-SQLでさまざまな目的に使用できるため、前のステートメントに含まれないようにするためです。

それがバッチの最初のステートメントである場合、それは必要ないと思います。

10
swasheck