回答:
使用するタイミングと理由に答える前GO
に、何が何で、何がそうでないかを正確に理解することが最重要です。
このキーワードGO
は、SQL Server Management StudioおよびSQLCMDで、1つのことだけを示すために使用されます。ステートメントのバッチの終わりです。実際、バッチを終了するために使用するものを「GO」以外に変更することもできます。
上記のスクリーンショットは、構成可能なSSMS内のオプションです。
しかし、バッチとは何ですか?? このBOLリファレンスは、それを最もよく言っています:
バッチは、実行のためにアプリケーションからSQL Serverに同時に送信される1つ以上のTransact-SQLステートメントのグループです。
そのような単純な。これは、アプリケーション(はい...アプリケーション)がSQL Serverにステートメントを送信する単なるカスタム方法です。これのアプリケーションに見える例を見てみましょう。PowerShellを使用して、ステートメントとバッチをSQL Serverに送信するためにアプリケーションが行うことを模倣します。
$ConnectionString = "data source = SomeSQLInstance; initial catalog = AdventureWorks2012; trusted_connection = true; application name = BatchTesting;"
try {
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection($ConnectionString)
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.Connection = $SqlConnection
# first batch of statements
#
$SqlCmd.CommandText = "
select * from humanresources.department where departmentid = 1;
select * from humanresources.department where departmentid = 2;
select * from humanresources.department where departmentid = 3;
select * from humanresources.department where departmentid = 4;"
# execute the first batch
#
$SqlConnection.Open()
$SqlCmd.ExecuteNonQuery()
$SqlConnection.Close()
# second batch of statements
#
$SqlCmd.CommandText = "
select * from humanresources.department where departmentid = 5;
select * from humanresources.department where departmentid = 6;
select * from humanresources.department where departmentid = 7;
select * from humanresources.department where departmentid = 8;"
# execute the second batch
#
$SqlConnection.Open()
$SqlCmd.ExecuteNonQuery()
$SqlConnection.Close()
}
catch {
$SqlCmd.Dispose()
$SqlConnection.Dispose()
Write-Error $_.Exception
}
コメントでわかりますが、上記のように、プログラムで2つのバッチをSQL Serverに送信していることがわかります。ただし、それを確認しましょう。ここでの私の選択は、拡張イベントを使用することです。
create event session BatchTesting
on server
add event sqlserver.sql_batch_starting
(
set
collect_batch_text = 1
where
(
sqlserver.client_app_name = N'BatchTesting'
)
),
add event sqlserver.sql_batch_completed
(
set
collect_batch_text = 1
where
(
sqlserver.client_app_name = N'BatchTesting'
)
),
add event sqlserver.sql_statement_starting
(
set
collect_statement = 1
where
(
sqlserver.client_app_name = N'BatchTesting'
)
),
add event sqlserver.sql_statement_completed
(
set
collect_statement = 1
where
(
sqlserver.client_app_name = N'BatchTesting'
)
)
add target package0.event_file
(
set
filename = N'<MyXelLocation>\BatchTesting.xel'
);
go
alter event session BatchTesting
on server
state = start;
go
このXEventsセッションが実行しているのは、次の名前のアプリケーションから開始および完了するステートメントとバッチをキャプチャすることです "BatchTesting"
ことです(PowerShellコード例で接続文字列に気付いた場合は、「application 「名前」接続文字列パラメータとそのフィルタリング)。
PowerShellコードを実行してこれらのバッチとステートメントを送信すると、次の結果が表示されます。
スクリーンショットからわかるように、ステートメントが2つの異なるバッチにどのように分割されているかは明らかです。これは、バッチを呼び出すために使用した手段でも明らかです。batch_text
の最初の出現を調べると、sql_batch_starting
そのバッチに含まれるすべてのステートメントを見ることができます。
select * from humanresources.department where departmentid = 1;
select * from humanresources.department where departmentid = 2;
select * from humanresources.department where departmentid = 3;
select * from humanresources.department where departmentid = 4;
バッチとは何かについての説明とともに、バッチをいつ終了するかという質問に対する答えが得られます。バッチのルールは、バッチに関するこのBOLリファレンスに記載されています。
CREATE DEFAULT、CREATE FUNCTION、CREATE PROCEDURE、CREATE RULE、CREATE SCHEMA、CREATE TRIGGER、およびCREATE VIEWステートメントは、バッチ内の他のステートメントと組み合わせることはできません。CREATEステートメントはバッチを開始する必要があります。そのバッチに続く他のすべてのステートメントは、最初のCREATEステートメントの定義の一部として解釈されます。
テーブルを変更してから、同じバッチで新しい列を参照することはできません。
EXECUTEステートメントがバッチの最初のステートメントである場合、EXECUTEキーワードは必要ありません。EXECUTEステートメントがバッチ内の最初のステートメントでない場合、EXECUTEキーワードが必要です。
同様に、バッチ中に発生する特定のランタイムエラー(コンパイルエラーではバッチの実行が許可されない)は、さまざまな動作を引き起こす可能性があります:バッチを完全に中止するか、バッチを続行して問題のあるステートメントのみを中止します(上記リンクには、2つの非常に良い例があります。たとえば、算術オーバーフローエラーはバッチの実行を停止しますが、制約違反エラーは現在のステートメントの完了を妨げますが、バッチの実行は継続します。
しかし、私たちの専門家の多くのものと同様に、個人的な好みは、T-SQLコードの個人およびライターとしてのあなたがどのようにバッチを終了するかを支える大きな推進力になります。絶対に必要な場合にのみバッチを明示的に定義する人(上記の要件を参照)と、SSMSのクエリウィンドウで1つのステートメントのみを実行している場合でも、バッチをプログラムで100%終了する人もいます。ほとんどの人は通常、これらの2つの境界の中間に位置します。価値のあることとして、ステートメントターミネーターには同じ要件があり、強制要件もほとんどありません。このすべての大部分はコードスタイルであり、強制されていません(SSMSおよびSQLCMDで)。