SQL Server:什么是批处理语句(即使用“GO”)?

我知道在SQL Server GO 被认为是一个批处理分隔符 。

我的问题是: 有一个批分隔符是什么意思? 它给你什么好处,你为什么要使用它?

例子:我经常看到它在SQL代码中使用如下,我不明白为什么这将被视为最佳做法。 至于我可以告诉代码将没有所有的GO语句相同:

 USE AdventureWorks2012; GO BEGIN TRANSACTION; GO IF @@TRANCOUNT = 0 BEGIN SELECT FirstName, MiddleName FROM Person.Person WHERE LastName = 'Adams'; ROLLBACK TRANSACTION; PRINT N'Rolling back the transaction two times would cause an error.'; END; ROLLBACK TRANSACTION; PRINT N'Rolled back the transaction.'; GO 

(来源: technet文档 ):

在这个例子中,这是没有任何用处的。

然而,许多报表必须是批次中唯一的报表。

CREATE PROCEDURE

通常,在进行模式更改之后(例如,将新列添加到现有表),使用新模式的语句必须在不同批次中单独编译。

通常,提交由GO分隔的单独批次的替代方法是使用EXEC在子批次中执行SQL

正如TechNet所说 , GO它表示SQL实用程序的SQL批处理结束。 例如,当SQL Server Management Studio遇到批分隔符时,它知道到目前为止所有文本都是独立的SQL查询。

我们在软件中使用了类似的技术。 我们将所有的特效,模式脚本,数据转换等都保存在SQL脚本文件中(签入到源代码pipe理中)。 当我们的安装程序读取其中一个脚本文件时,GO会告诉我们的parsing器“您可以运行您已经阅读过的SQL”。

GO这样的批处理分隔符的GO是,您可以将两个SQL查询一起包含在通常会导致错误的相同脚本中。 例如,尝试在相同的脚本文件中删除并重新创build相同的存储过程:

 if exists (select * from sys.procedures where name = 'sp_test') drop procedure sp_test create procedure sp_test as begin select 1 end 

如果你运行上面的代码,你会得到一个错误:

消息156,级别15,状态1,过程sp_test,行5关键字'begin'附近的语法不正确。

SSMS会告诉你这个错误:

语法不正确。 'CREATE PROCEDURE'必须是批处理中唯一的语句。

使用批处理分隔符可以帮助你解决这个错误:

 if exists (select * from sys.procedures where name = 'sp_test') drop procedure sp_test GO create procedure sp_test as begin select 1 end 

如果您希望源代码pipe理中的单个SQL脚本维护存储过程或函数,这非常方便。 我们经常使用这种模式。

另一个有趣的事情是你可以用它来多次运行一个查询:

 INSERT INTO MyTable (...) ... GO 10 -- run all the above 10 times! 

正如这个SO问题的答案所示,您也可以将其configuration为任何您想要的。 如果你想和同事混淆,把批处理分隔符设置为“WHERE”而不是“GO”。 有趣! 🙂

就像Martain说的那样,像CREATE PROCEDURE这样的陈述必须是一批中唯一的。

例如,我创build存储过程并向某个用户添加权限时使用批分隔符。 如果我遗漏了“去”,那么我最终会得到一个存储过程,每次运行时都会赋予权限。 这样我就可以同时写入它们,并且确保我没有编写存储过程,当我打电话给它时会中断。 例如

 create procedure [procedurename] (parameters) as begin select prefname, lastname from people end go grant execute on [procedurename] to [username]