我很好奇,因为许多Microsoft文档等已经在每个声明之后开始使用它,或者我刚刚开始注意到它.
什么被认为是最佳做法?
解决方法
GO
是什么,以及它不是什么.
sql Server Management Studio和sqlCMD使用关键字GO来表示一件事,只有一件事:一批语句的结束.实际上,您甚至可以将用于终止批次的内容更改为“GO”以外的其他内容:
上面的屏幕截图是SSMS中可配置的选项.
但什么是批次? This BOL reference说得最好:
A batch is a group of one or more Transact-sql statements sent at the same time from an application to sql Server for execution.
就那么简单.它只是一种自定义方式,应用程序(是……应用程序)向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代码以发送这些批次和语句后,我看到以下结果:
正如您从屏幕截图中看到的那样,很清楚如何将语句划分为两个不同的批次,这也是我们用来调用批次的方法.如果我们查看第一次出现的sql_batch_starting的batch_text,我们可以看到该批次中包含的所有语句:
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;
通过对批处理内容的解释,现在可以回答您何时终止批处理的问题.批次规则见于this BOL reference regarding batches:
CREATE DEFAULT,CREATE FUNCTION,CREATE PROCEDURE,CREATE RULE,CREATE
SCHEMA,CREATE TRIGGER,and CREATE VIEW statements cannot be combined
with other statements in a batch. The CREATE statement must start the
batch. All other statements that follow in that batch will be
interpreted as part of the definition of the first CREATE statement.A table cannot be changed and then the new columns referenced in the
same batch.If an EXECUTE statement is the first statement in a batch,the EXECUTE
keyword is not required. The EXECUTE keyword is required if the
EXECUTE statement is not the first statement in the batch.
同样,批处理期间发生的某些运行时错误(编译错误将不允许执行批处理)可能会导致不同的行为:完全中止批处理,或继续批处理并仅中止违规语句(上述link给出了两个非常好的例子:例如,算术溢出错误将停止批处理的执行,而约束违规错误只会阻止当前语句完成但批处理将继续执行).
然而,就像我们职业中的许多事情一样,个人偏好将成为您作为个人和T-sql代码编写者终止批次的巨大推动力.有些人只有在必要时才明确定义批次(参见上面的那些要求),而其他人在100%的时间内以编程方式终止批量,即使他们只是在SSMS的查询窗口中执行单个语句.大多数人通常会落在这两个边界的中间位置.对于它的价值,语句终止符具有相同的跟随,并且强制要求也很少.所有这一切的很大一部分是代码风格,它没有强制执行(在SSMS和sqlCMD中).