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


13

Aaron Bertrandが数値テーブルの代わりにCTEを使用することを提案しているStackOverflowの投稿を見ているところです。私の質問は、なぜ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何かに解析されないようにするためですか?WITHの前にセミコロンを使用することについて、SQL Server 2005 BOLには何も表示されません。


回答:


25

ここで、またはStackOverflowで投稿するときは常に行います。WITHなぜなら、キーワードがオーバーロードされているため、前のコマンドには終了セミコロンが必要だからです。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;

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


1
2012年には、i.stack.imgur.comEND TRY / rc6dw.pngの後のセミコロンが原因でのみ同じエラーメッセージが表示されます。そのセミコロンを削除すると、すべてが機能します。
アーロンバートランド

セミコロンBEGIN CATCHは、で導入された単一の複合文の一部であるため、前に置くことはできないと思いますBEGIN TRYIFステートメントの前にセミコロンを置くのと同じELSEです。
アンドリーM

@AndriyM私はここでルールについてもっと詳細な会話をしてきました。理由がわからないからではなく、出くわしたすべての人にとって驚きだからです。:-)
アーロンバートランド

10

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.