在检查Web上的某些代码和SQL Server Management Studio生成的脚本时,我注意到某些语句以分号结束。
那我什么时候应该使用它?
答案 0 :(得分:136)
来自Ken Powers的SQLServerCentral.Com article:
分号
分号字符是语句终止符。它是ANSI SQL-92标准的一部分,但从未在Transact-SQL中使用。实际上,可以在不遇到分号的情况下对T-SQL进行编码。
<强>用法强>
有两种情况必须使用分号。第一种情况是使用公用表表达式(CTE),而CTE不是批处理中的第一个语句。第二个是发布Service Broker语句,Service Broker语句不是批处理中的第一个语句。
答案 1 :(得分:71)
默认情况下,SQL语句以分号结束。除非(很少)设置新的语句终止符,否则使用分号来终止语句。
如果您只发送一份声明,从技术上讲,您可以免除声明终止符;在脚本中,当你发送多个语句时,你需要它。
实际上,即使您只是向数据库发送一条语句,也要包含终结符。
编辑:响应那些说法语句[特定RDBMS]不需要语句终止符,虽然这可能是真的,但它们是ANSI SQL标准所要求的。在所有编程中,如果我们能够在不损失功能的情况下遵守标准,我们就应该这样做,因为那时我们的代码或习惯都不会与一个专有供应商联系在一起。
使用一些C编译器,即使标准要求main返回int,也可能使main返回void。但这样做会使我们的代码和我们自己的可移植性降低。
有效编程的最大困难不是学习新事物,而是学习不良习惯。在某种程度上,我们可以首先避免获得不良习惯,这对我们,我们的代码以及任何阅读或使用我们代码的人来说都是一种胜利。
答案 2 :(得分:24)
在SQL2008 BOL中,他们说在下一版本中需要使用分号。因此,请始终使用它。
参考:
答案 3 :(得分:22)
如果我正确阅读,则需要使用分号来结束TSQL语句。 http://msdn.microsoft.com/en-us/library/ms143729%28v=sql.120%29.aspx
编辑: 我找到了一个SSMS 2008R2的插件,它将格式化你的脚本并添加分号。我认为它仍处于测试阶段......
http://www.tsqltidy.com/tsqltidySSMSAddin.aspx
编辑: 我找到了一个更好的免费工具/插件,称为ApexSQL ... http://www.apexsql.com/
答案 4 :(得分:14)
你必须使用它。
使用分号终止语句的做法是标准的,实际上是一项要求 在其他几个数据库平台上。 SQL Server仅特别需要分号 案例 - 但在不需要分号的情况下,使用分号不会导致问题。 我强烈建议您采用以分号结束所有语句的做法。 这样做不仅可以提高代码的可读性,而且在某些情况下可以提高代码的可读性 救你一些悲伤。 (如果需要分号且未指定分号,则会出现错误消息SQL 服务器产生并不总是很清楚。)
最重要的是:
SQL Server文档表明没有终止T-SQL语句 分号是不推荐使用的功能。这意味着长期目标是强制使用 未来版本的产品中的分号。这是进入的另一个原因 终止所有陈述的习惯,即使在目前不需要的情况下也是如此。
来源:Itzik Ben-Gan的 Microsoft SQL Server 2012 T-SQL基础。
您始终必须使用;
的原因的示例是以下两个查询(从此post复制):
BEGIN TRY
BEGIN TRAN
SELECT 1/0 AS CauseAnException
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE()
THROW
END CATCH
BEGIN TRY
BEGIN TRAN
SELECT 1/0 AS CauseAnException;
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE();
THROW
END CATCH
答案 5 :(得分:9)
个人观点:仅在需要时使用它们。 (有关所需列表,请参阅TheTXI上面的答案。)
由于编译器不需要它们,你可以将它们全部放在一边,但为什么呢?编译器不会告诉你你忘记了哪一个,所以你最终会使用不一致。
[此意见特定于SQL Server。其他数据库可能有更严格的要求。如果您正在编写SQL以在多个数据库上运行,则您的要求可能会有所不同。]
tpdi如上所述,“在脚本中,当您发送多个声明时,您需要它。”这实际上是不正确的。你不需要它们。
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional';
PRINT 'Semicolons are optional';
输出:
Semicolons are optional
Semicolons are optional
Semicolons are optional
Semicolons are optional
答案 6 :(得分:3)
分号似乎不应与游标操作一起使用:OPEN
,FETCH
,CLOSE
和DEALLOCATE
。我只是浪费了几个小时。我仔细看了一下BOL,发现这些游标语句的语法中没有显示[;] !!
所以我有:
OPEN mycursor;
这给了我错误16916。
可是:
OPEN mycursor
的工作。
答案 7 :(得分:3)
我还有很多东西需要学习T-SQL,但是在处理一些事务代码(以及基于stackoverflow和其他站点的示例代码)时,我发现了一个似乎需要分号的情况,如果它如果缺少,则该语句似乎根本不执行,并且不会引发错误。上述任何答案似乎都没有涵盖这一点。 (这是使用MS SQL Server 2012.)
一旦我按照我想要的方式运行事务,我决定在它周围放一个try-catch,这样如果有任何错误就会回滚。只有在执行此操作后,才会提交事务(SSMS在尝试关闭窗口时会显示一条消息,提示您存在未提交的事务。
所以这个
COMMIT TRANSACTION
在BEGIN TRY / END TRY块之外的工作正常以提交事务,但在块内它必须是
COMMIT TRANSACTION;
请注意,在尝试关闭查询选项卡之前,没有提供任何错误或警告,也没有表明交易仍然未提交。
幸运的是,这会导致如此巨大的问题,很明显存在问题。不幸的是,由于没有报告错误(语法或其他方面),因此问题并不是很明显。
相反,ROLLBACK TRANSACTION似乎在带有或不带分号的BEGIN CATCH块中同样有效。
这可能有一些逻辑,但它感觉任意和Alice-in-Wonderland-ish。
答案 8 :(得分:2)
根据Transact-SQL Syntax Conventions (Transact-SQL)(MSDN)
Transact-SQL语句终止符。虽然此版本的SQL Server中的大多数语句都不需要分号,但在将来的版本中将需要使用分号。
(另见@gerryLowry的评论)
答案 9 :(得分:0)
在批处理中使用DISABLE或ENABLE TRIGGER语句时,其前面的语句必须以分号结尾。否则,您将收到语法错误。我用这个撕掉了我的头发......然后,我偶然发现了这个MS Connect项目。它已关闭,因为无法修复。
请参阅here
答案 10 :(得分:0)
注意:这回答了所写的问题,但不是所述的问题。在此处添加,因为人们将搜索它
在递归CTE语句中WITH
之前也使用了分号:
;WITH Numbers AS
(
SELECT n = 1
UNION ALL
SELECT n + 1
FROM Numbers
WHERE n+1 <= 10
)
SELECT n
FROM Numbers
此查询将生成一个名为Numbers的CTE,它由整数[1..10]组成。这是通过创建一个值为1的表来完成的,然后递归直到达到10。
答案 11 :(得分:0)
如果您希望在SQLServer中获得随机命令超时错误,请在CommandText字符串末尾留下分号。
我不知道这是否记录在任何地方或是否是一个错误,但它确实发生了,我从痛苦的经历中学到了这一点。
我使用SQLServer 2008具有可验证且可重现的示例。
又名 - &gt; 实际上,即使您只是向数据库发送一条语句,也要始终包含终结符。
答案 12 :(得分:-1)
分号并不总是在复合SELECT语句中工作。
比较这两个不同版本的普通复合SELECT语句。
代码
DECLARE @Test varchar(35);
SELECT @Test=
(SELECT
(SELECT
(SELECT 'Semicolons do not always work fine.';);););
SELECT @Test Test;
返回
Msg 102, Level 15, State 1, Line 5
Incorrect syntax near ';'.
然而,代码
DECLARE @Test varchar(35)
SELECT @Test=
(SELECT
(SELECT
(SELECT 'Semicolons do not always work fine.')))
SELECT @Test Test
返回
Test
-----------------------------------
Semicolons do not always work fine.
(1 row(s) affected)