Web上のいくつかのコードとSQL Server Management Studioによって生成されたスクリプトを確認していると、一部のステートメントがセミコロンで終わっていることがわかりました。
それで、いつそれを使うべきですか?
Web上のいくつかのコードとSQL Server Management Studioによって生成されたスクリプトを確認していると、一部のステートメントがセミコロンで終わっていることがわかりました。
それで、いつそれを使うべきですか?
回答:
Ken PowersによるSQLServerCentral.Comの記事から:
セミコロン
セミコロン文字はステートメントの終了文字です。これはANSI SQL-92標準の一部ですが、Transact-SQL内では使用されていません。実際、セミコロンに出くわすことなく、T-SQLを何年もコーディングすることが可能でした。
使用法
セミコロンを使用する必要がある状況は2つあります。最初の状況は、共通テーブル式(CTE)を使用する場合で、CTEはバッチの最初のステートメントではありません。2番目はService Brokerステートメントを発行する場所で、Service Brokerステートメントはバッチの最初のステートメントではありません。
THROW
Service Brokerのステートメントは?我々は以前、この例ではスローにセミコロンを含める必要があります:BEGIN ;THROW @Error, 'Invalid FundingID', 2; RETURN END
MERGE
例も)。他の回答で述べたように、ANSI標準では必須です
デフォルトでは、SQLステートメントはセミコロンで終了します。新しいステートメントターミネータを(まれに)設定していない限り、セミコロンを使用してステートメントを終了します。
ステートメントを1つだけ送信する場合、技術的にはステートメントターミネータを省略できます。スクリプトでは、複数のステートメントを送信するときに必要になります。
実際には、データベースにステートメントを1つだけ送信する場合でも、常にターミネータを含めます。
編集:[特定のRDBMS]ではステートメントターミネーターは不要であると述べていることに対応して、それは当てはまる場合がありますが、ANSI SQL標準では必須です。すべてのプログラミングにおいて、機能を失うことなく標準に準拠できる場合は、その必要があります。それは、コードも習慣も、1つの専有ベンダーに結び付けられていないためです。
一部のCコンパイラでは、標準でメインがintを返すように要求している場合でも、メインの戻りが無効になる可能性があります。しかし、これを行うと、コード自体、および移植性が低下します。
効果的なプログラミングの最大の困難は、新しいことを学ぶことではなく、悪い習慣を身につけないことです。そもそも悪い習慣を身につけないようにすることができる範囲で、それは私たちにとって、私たちのコードにとって、そして私たちのコードを読んだり使用したりする人にとっての勝利です。
SQL2008 BOLでは、次のリリースではセミコロンが必要になると述べています。したがって、常にそれを使用してください。
参照:
あなたはそれを使わなければなりません。
セミコロンを使用してステートメントを終了する方法は標準であり、実際には他のいくつかのデータベースプラットフォームでは要件となっています。SQL Serverは特定の場合にのみセミコロンを必要としますが、セミコロンが不要な場合は、セミコロンを使用しても問題は発生しません。すべてのステートメントをセミコロンで終了する方法を採用することを強くお勧めします。これにより、コードが読みやすくなるだけでなく、場合によっては、悲しみを和らげることができます。(セミコロンが必要で指定されていない場合、SQL Serverが生成するエラーメッセージは必ずしも明確ではありません。)
そして最も重要なこと:
SQL Serverのドキュメントには、T-SQLステートメントをセミコロンで終了しないことは非推奨の機能であると記載されています。つまり、長期的な目標は、製品の将来のバージョンでセミコロンの使用を強制することです。これが、現在必要とされていない場合でも、すべてのステートメントを終了する癖をつけるもう1つの理由です。
出典: Itzik Ben-GanによるMicrosoft SQL Server 2012 T-SQLの基礎。
常に使用する必要がある理由の例;
は、次の2つのクエリ(この投稿からコピー)です。
BEGIN TRY
BEGIN TRAN
SELECT 1/0 AS CauseAnException
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE()
THROW
END CATCH
BEGIN TRY
BEGIN TRAN
SELECT 1/0 AS CauseAnException;
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE();
THROW
END CATCH
not using them
非推奨のテクニックであることが発表されている場合は、それらを使用する必要があります。そうでなければ、将来苦しむリスクがあります。ジョブのアップグレード/切り替えを計画しておらず、常にSQL Server 2000で作業する場合は、安全です:-)
Incorrect syntax near 'THROW'.
た例では、SQL Server 2008(10.0.6241.0)が生成されます。これは、私が作業中に処理する必要があるバージョンです。それは2012年に示されているように動作します。廃止されたため、セミコロンの使用を開始すると確信しました。ほとんどの場合、それが2008年に問題になるとは思わない。
これを正しく読んだ場合、セミコロンを使用してTSQLステートメントを終了する必要があります。 http://msdn.microsoft.com/en-us/library/ms143729%28v=sql.120%29.aspx
編集:スクリプトをフォーマットしてセミコロンを追加するSSMS 2008R2のプラグインを見つけました。まだベータ版だと思うけど...
http://www.tsqltidy.com/tsqltidySSMSAddin.aspx
編集:ApexSQLと呼ばれるさらに優れた無料のツール/プラグインを見つけました... http://www.apexsql.com/
個人的な意見:必要な場合にのみ使用してください。(必要なリストについては、上記のTXIの回答を参照してください。)
コンパイラはそれらを必要としないので、それらをすべて配置できますが、なぜですか?コンパイラは、どこで忘れたかを教えてくれないので、一貫性のない使用法になります。
[この意見はSQL Serverに固有のものです。他のデータベースには、より厳しい要件がある場合があります。SQLを作成して複数のデータベースで実行する場合、要件は異なる場合があります。]
tpdiは上記のように述べています。「スクリプトでは、複数のステートメントを送信するので、それが必要です。」それは実際には正しくありません。あなたはそれらを必要としません。
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional';
PRINT 'Semicolons are optional';
出力:
Semicolons are optional
Semicolons are optional
Semicolons are optional
Semicolons are optional
T-SQLについてはまだ多くのことを学ぶ必要がありますが、トランザクションのいくつかのコード(およびstackoverflowや他のサイトの例に基づいたコード)を作成する際に、セミコロンが必要であると思われるケースがあり、それがない場合は、ステートメントはまったく実行されていないようで、エラーは発生しません。これは上記の回答のいずれにも含まれていないようです。(これはMS SQL Server 2012を使用していました。)
トランザクションを希望どおりに機能させると、その周りにtry-catchを配置することにしました。エラーが発生した場合は、ロールバックされます。これを実行した後でのみ、トランザクションはコミットされませんでした(SSMSは、コミットされていないトランザクションがあることを警告する素敵なメッセージでウィンドウを閉じようとしたときにこれを確認します。
したがって、この
COMMIT TRANSACTION
BEGIN TRY / END TRYブロックの外側はトランザクションをコミットするためにうまく機能しましたが、ブロックの内側では
COMMIT TRANSACTION;
エラーや警告は表示されず、クエリタブを閉じようとするまでトランザクションがまだコミットされていないことを示すものではありません。
幸いなことに、これは非常に大きな問題を引き起こし、問題があることがすぐに明らかになります。残念ながら、エラー(構文など)は報告されていないため、問題が何であるかはすぐにはわかりませんでした。
逆に、ROLLBACK TRANSACTIONは、セミコロンの有無にかかわらず、BEGIN CATCHブロックでも同じように機能するようです。
これにはいくらかの論理があるかもしれませんが、それは恣意的で不思議の国のアリスらしいです。
COMMIT TRANSACTION
は、オプションのトランザクション/保存ポイント名(これは無視されます)を受け入れることです。終了セミコロンがないCOMMIT TRANSACTION
と、識別子として解析される場合、次のシンボルを食べる可能性があり、コードのセマンティクスを根本的に変える可能性があります。これによりエラーが発生したCATCH
場合、はCOMMIT
実行されずにトリガーされることがあります。逆に、ROLLBACK TRANSACTION
このようなオプションの識別子も受け入れますが、そこでの解析エラーは、トランザクションがとにかくロールバックされる可能性が高いです。
:セミコロンがカーソル操作と連動して使用すべきではないと思われるOPEN
、FETCH
、CLOSE
とDEALLOCATE
。私はこれで数時間を無駄にしました。BOLを詳しく調べたところ、[;]がこれらのカーソルステートメントの構文に表示されていないことに気づきました。
だから私は持っていました:
OPEN mycursor;
これにより、エラー16916が発生しました。
だが:
OPEN mycursor
働いた。
よると、Transact-SQLの構文規則(のTransact-SQL)(MSDN)
Transact-SQLステートメントの終了文字。セミコロンは、このバージョンのSQL Serverのほとんどのステートメントでは必要ありませんが、将来のバージョンでは必要になるでしょう。
(@gerryLowryのコメントも参照)
注:これは書かれた質問に答えますが、述べられた問題には答えません。人々がそれを探すので、ここに追加します
セミコロンは、以前WITH
に再帰CTEステートメントでも使用されています。
;WITH Numbers AS
(
SELECT n = 1
UNION ALL
SELECT n + 1
FROM Numbers
WHERE n+1 <= 10
)
SELECT n
FROM Numbers
このクエリは、整数[1..10]で構成されるNumbersというCTEを生成します。これは、値が1のテーブルのみを作成し、10に達するまで再帰的に実行されます。
SQLServerでランダムなコマンドタイムアウトエラーが発生する場合は、CommandText文字列の最後のセミコロンを省略してください。
これがどこに文書化されているのか、それともバグなのかはわかりませんが、実際に起こり、苦い経験からこれを学びました。
SQLServer 2008を使用して検証および再現可能な例があります。
別名-> 実際には、データベースにステートメントを1つだけ送信する場合でも、常にターミネータを含めます。
セミコロンは常に複合SELECTステートメントで機能するとは限りません。
単純な複合SELECTステートメントのこれら2つの異なるバージョンを比較します。
コード
DECLARE @Test varchar(35);
SELECT @Test=
(SELECT
(SELECT
(SELECT 'Semicolons do not always work fine.';);););
SELECT @Test Test;
戻り値
Msg 102, Level 15, State 1, Line 5
Incorrect syntax near ';'.
ただし、コード
DECLARE @Test varchar(35)
SELECT @Test=
(SELECT
(SELECT
(SELECT 'Semicolons do not always work fine.')))
SELECT @Test Test
戻り値
Test
-----------------------------------
Semicolons do not always work fine.
(1 row(s) affected)