在SQL Server中,何时应使用GO,何时应使用分号;?

131

我一直很困惑应该在命令后面使用GO关键字,并且是否需要在命令结尾加分号。它们之间的区别是什么,为什么/何时应该使用它们?

当我在SQL Server Management Studio中运行Generate-script时,似乎到处都在使用GO,但没有使用分号。


5个回答

114

GO 只与 SSMS 相关 - 它并不是实际的 Transact SQL,而是告诉 SSMS 按顺序将每个 GO 之间的 SQL 语句发送到单独的批处理中。

; 是 SQL 语句分隔符,但大多数情况下,引擎可以解释您的语句在哪里断开。

主要的例外和使用 ; 最频繁的地方是在公共表达式语句之前。


9
强调GO不是 T-SQL 部分,而;是。 - msarchet
3
MERGE语句必须以分号结尾。 - onedaywhen
16
更新:在 SQL Server 2012 中,不使用分号已被弃用,这意味着在下一个版本中将需要使用分号。因此,在迁移时使用分号是一个好习惯(而且它也是一个标准)。来源:http://technet.microsoft.com/zh-cn/library/ms143729.aspx 或 SQL Server 2012 书籍:http://shop.oreilly.com/product/0790145321978.do - Paweł Bulwan
3
SQL 2014仍将分号列为下一个版本所需的内容。我想知道它何时会被弃用。http://technet.microsoft.com/en-us/library/ms143729.aspx - Frank
3
+buli并没有说;已经过时,而是不使用它已经过时了,也就是说,根据来源,使用;将变得强制性。 - cjk
显示剩余2条评论

100
您在生成的DDL脚本中看到许多“GO”的原因是由于以下关于批处理的规则:CREATE DEFAULT、CREATE FUNCTION、CREATE PROCEDURE、CREATE RULE、CREATE TRIGGER和CREATE VIEW语句不能与其他语句组合在一个批处理中。CREATE语句必须开始批处理。在该批处理中后跟的所有其他语句将被解释为第一个CREATE语句的定义的一部分。
生成DDL的一个用例是在单个文件中生成多个对象。因此,DDL生成器必须能够生成批处理。正如其他人所说,GO语句结束了批处理。

12
这是唯一一个真正回答了“何时应该使用GO?”这个问题的人。 - Roimer
在我看来,GO会终止包含可能包含;语句终止符的SQL的对象创建语句。在另一个DBMS中,我已经看到了设置终止字符串的能力。例如,您可以指定语句以两个管道字符||结尾。然后,您可以发出CREATE PROCEDURE…以;结尾的大量SQL… ||,双管道符号结束CREATE PROCEDURE语句。所以我的问题是这是否类似于MS GO语句?其次,您能否重新定义SQLSERVER中的终止字符串? - youcantryreachingme
@youcantryreachingme 我不知道这在2010年是否正确,但现在看来是可以的。请参见SSMS:批处理分隔符。我不确定其限制是什么。 - Conrad Frix
在回答GO部分时,它未能解决它和分号之间的区别。 - pbaldridge

45

GO

GO是批处理分隔符。这意味着该批处理中的所有内容都局限于该特定批处理中。

任何变量、表变量等声明不会越过 GO 语句。

#Temp表对连接局部有效,因此它们跨越GO语句。

Semicolon

分号是语句终止符。这仅用于标识特定语句已结束。

在大多数情况下,语句语法本身足以确定语句的结尾。

然而,CTE要求WITH是第一条语句,因此需要在WITH之前使用分号。


5
一个 MERGE 语句必须以分号结束。 - onedaywhen

12

在每个SQL语句的末尾使用分号作为终止符是应该的,这在SQL标准中有定义。

当然,SQL Server通常允许您省略语句终止符,但为什么要养成坏习惯呢?

正如其他人所指出的那样,公共表达式(CTE)前面的语句必须以分号结束。因此,由于一些人没有完全接受分号终止符,我们会看到这样的写法:

;WITH ...

我认为它看起来非常奇怪。我想在在线论坛中,当您无法确定将粘贴到其中的代码的质量时,这是有意义的。

另外,MERGE语句必须以分号结束。你看到规律了吗?这些是最新添加到TSQL中的一些功能,紧密遵循SQL标准。看起来SQL Server团队正在要求使用分号终止符。


2
“我认为这看起来非常奇怪”,我完全同意。而且不断重复这种写法会导致出现奇怪的问题,比如这个或者这个 - user330315
SQL Server 不允许您懒散 - 它允许您省略冗余的语句终止符; T-SQL,像大多数其他 SQL 一样,不是纯标准 SQL,更像是一个抽象基类 - 在实践中不被使用,而是使用 DB 引擎自己的方言。 - ProfK
@ProfK:感谢您在评论中使用标点符号,使我能够轻松阅读和理解,特别是句子终止符。不过,您使用连字符的方式并不符合标准英语…… - onedaywhen
然而,SQL Management Studio脚本生成向导生成的INSERT语句没有分号并且带有GO语句。如果我想要我的数据转储能够高效地在SSMS之外被导入,也许我应该用COMMIT替换所有的GO语句(并添加相应的BEGIN TRANSACTION语句)。 - JustAMartin

9

GO是批处理终止符,分号是语句终止符。

当您想在一个脚本中使用多个create proc语句时,需要使用GO,因为create proc必须是批处理中的第一条语句。如果使用公共表达式,则其前面的语句需要用分号终止。


MERGE语句必须以分号结尾。 - onedaywhen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接