Answers:
在回答何时使用它以及为什么使用之前,首先要弄清什么GO
是什么,什么不是什么。
GO
SQL Server Management Studio和SQLCMD使用该关键字来表示一件事而只有一件事:一批语句的末尾。实际上,您甚至可以将用于终止批次的内容更改为“ GO”以外的内容:
上面的屏幕截图是SSMS中可配置的选项。
但是什么是批次? 这个BOL参考书说得最好:
批处理是一组从一个应用程序同时发送到SQL Server以便执行的一个或多个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
}
这些注释将其遗忘了,但是您可以在上面看到我们正在以编程方式将两个批处理发送到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代码示例中注意到了我的连接字符串,这是一种使用“应用程序”查看特定事件发起者的快速方法名称”连接字符串参数并从中过滤掉)。
执行PowerShell代码发送那些批处理和语句后,我看到以下结果:
从屏幕截图中可以看到,很明显,如何将语句分为两个不同的批处理,这也可以通过我们用来调用批处理的方式看出。如果查看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关键字。
同样,在批处理期间发生的某些运行时错误(编译错误将不允许开始执行批处理)可能导致不同的行为:完全中止该批处理,或继续该批处理并仅中止有问题的语句(上述内容)链接给出了两个非常好的示例:例如,算术溢出错误将停止批处理的执行,而违反约束错误将仅阻止当前语句完成,而批处理将继续执行。
但是,就像我们行业中的许多事情一样,个人喜好将成为您作为个人和T-SQL代码编写者终止批处理方式的巨大推动力。有些人仅在绝对必要时才明确定义批处理(请参见上文中的那些要求),而其他人即使在SSMS的“查询窗口”中仅执行单个语句时,也会以编程方式100%地终止批处理。大多数人通常落在这两个边界的中间。就其价值而言,语句终止符具有相同的追随者,并且执行需求也很少。所有这些的很大一部分是代码样式,在SSMS和SQLCMD中不强制使用。