在检查Web上的某些代码和SQL Server Management Studio生成的脚本时,我注意到某些语句以分号结尾。
那么我什么时候应该使用它呢?
在检查Web上的某些代码和SQL Server Management Studio生成的脚本时,我注意到某些语句以分号结尾。
那么我什么时候应该使用它呢?
Answers:
从Ken Powers 的SQLServerCentral.Com 文章中:
分号
分号字符是语句终止符。它是ANSI SQL-92标准的一部分,但从未在Transact-SQL中使用。确实,多年来编写T-SQL而不用遇到分号是可能的。
用法
在两种情况下,您必须使用分号。第一种情况是您使用通用表表达式(CTE),而CTE不是批处理中的第一条语句。第二个是您发布Service Broker语句的位置,而Service Broker语句不是批处理中的第一个语句。
THROW
服务经纪人声明吗?在此示例中,我们需要在投掷之前添加分号:BEGIN ;THROW @Error, 'Invalid FundingID', 2; RETURN END
MERGE
例如)。正如其他答案中提到的那样,在ANSI标准中它们是必需的
默认情况下,SQL语句以分号终止。除非您(很少)设置了新的语句终止符,否则请使用分号终止语句。
如果只发送一条语句,从技术上讲,您可以省去语句终止符;在脚本中,由于要发送多个语句,因此需要它。
实际上,即使您只向数据库发送一条语句,也要始终包含终止符。
编辑:响应那些说法,[特定的RDBMS]不需要语句终止符,尽管这可能是正确的,但ANSI SQL标准却要求它们。在所有编程中,如果我们可以遵守标准而又不损失功能,则应该这样做,因为那样一来,我们的代码或习惯就不会与一个专有供应商绑定。
对于某些C编译器,即使Standard要求main返回int,也可能具有main return void。但是这样做会使我们的代码以及我们自己的可移植性降低。
有效编程的最大困难是不学习新事物,这是在学习不良习惯。在某种程度上,我们首先可以避免养成不良习惯,这对我们,我们的代码以及任何阅读或使用我们的代码的人都是胜利。
他们说在SQL2008 BOL中,在下一发行版中将需要分号。因此,请始终使用它。
参考:
您必须使用它。
使用分号终止语句的做法是标准做法,实际上是其他几种数据库平台的要求。SQL Server仅在特定情况下才需要分号,但是在不需要分号的情况下,使用分号不会引起问题。我强烈建议您采用以分号终止所有语句的做法。这样做不仅可以提高代码的可读性,而且在某些情况下可以节省一些麻烦。(当需要分号并且未指定时,SQL Server产生的错误消息并不总是很清楚。)
最重要的是:
SQL Server文档指示不使用分号终止T-SQL语句是不推荐使用的功能。这意味着长期目标是在产品的未来版本中强制使用分号。这是养成终止所有语句的习惯的另一个原因,即使当前不需要它也是如此。
来源: Itzik Ben-Gan提供的Microsoft SQL Server 2012 T-SQL基础。
;
以下两个查询(从本篇文章复制而来)为什么总是必须使用的一个示例:
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
not using them
不建议使用分号,则应使用分号。如果不是这样,将来就有遭受痛苦的风险。如果您不打算升级/切换作业,并且始终要使用SQL Server 2000,那么您很安全:-)
Incorrect syntax near 'THROW'.
在SQL Server 2008(10.0.6241.0)上运行,这是我在工作中必须处理的版本。它的工作原理如2012年所示。由于过时,我被说服开始使用分号。我不认为大多数时候在2008年会出现问题。
如果我正确阅读了此内容,则必须使用分号结束TSQL语句。 http://msdn.microsoft.com/zh-cn/library/ms143729%28v=sql.120%29.aspx
编辑:我找到了一个SSMS 2008R2插件,它将格式化您的脚本并添加分号。我认为它仍处于测试阶段...
http://www.tsqltidy.com/tsqltidySSMSAddin.aspx
编辑:我发现了一个更好的免费工具/插件,名为ApexSQL ... http://www.apexsql.com/
个人观点:仅在需要时使用它们。(有关所需列表,请参见上面的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
关于T-SQL,我还有很多要学习的知识,但是在为事务编写一些代码(并将代码基于stackoverflow和其他站点的示例)时,我发现一种情况,似乎需要使用分号,并且如果缺少分号,该语句似乎根本不执行,并且不会引发任何错误。以上任何答案似乎都没有涵盖这一点。(这是使用MS SQL Server2012。)
一旦事务以我想要的方式工作,我决定围绕它进行尝试捕获,以便在出现任何错误时将其回滚。仅在执行完此操作后,交易才被提交(SSMS在尝试关闭窗口时通过一条漂亮的消息确认了这一点,该消息提醒您存在未提交的交易。
所以这
COMMIT TRANSACTION
在BEGIN TRY / END TRY块外部可以很好地提交事务,但是在块内部必须
COMMIT TRANSACTION;
请注意,在尝试关闭查询选项卡之前,没有提供错误或警告,也没有指示事务仍未提交的指示。
幸运的是,这引起了一个巨大的问题,以至于显而易见的是存在一个问题。遗憾的是,由于未报告任何错误(语法或其他错误),因此,问题出在哪儿并不能立即发现。
相反,ROLLBACK TRANSACTION在带有或不带有分号的BEGIN CATCH块中似乎同样有效。
这样做可能有逻辑,但感觉像是爱丽丝梦游仙境。
COMMIT TRANSACTION
接受一个可选的事务/保存点名称(它将忽略)。如果没有终止分号,COMMIT TRANSACTION
则如果将下一个符号解析为标识符,则可以使用下一个符号,这可以从根本上改变代码的语义。如果这随后导致错误,则CATCH
可能在COMMIT
没有执行的情况下触发。相反,尽管ROLLBACK TRANSACTION
也接受这样的可选标识符,但解析该错误最有可能导致交易无论如何被回滚。
看来,分号不应该结合使用游标操作:OPEN
,FETCH
,CLOSE
和DEALLOCATE
。我只是浪费了几个小时。我仔细查看了BOL,发现这些游标语句的语法中没有显示[;]!
所以我有:
OPEN mycursor;
这给了我错误16916。
但:
OPEN mycursor
工作了。
根据Transact-SQL语法约定(Transact-SQL)(MSDN)
Transact-SQL语句终止符。尽管在此版本的SQL Server中,大多数语句不需要分号,但在将来的版本中将需要分号。
(另请参阅@gerryLowry的评论)
注意:这将回答书面问题,但不能回答所陈述的问题。在这里添加它,因为人们会在搜索它
WITH
递归CTE语句之前也使用分号:
;WITH Numbers AS
(
SELECT n = 1
UNION ALL
SELECT n + 1
FROM Numbers
WHERE n+1 <= 10
)
SELECT n
FROM Numbers
此查询将生成一个名为Numbers的CTE,该CTE由整数[1..10]组成。通过创建仅具有值1的表,然后递归直到达到10来完成此操作。
如果您希望在SQLServer中收到随机的命令超时错误,请在CommandText字符串的末尾省略分号。
我不知道是否在任何地方对此进行了记录或它是否是一个错误,但是确实发生了,并且我从痛苦的经验中学到了这一点。
我有使用SQLServer 2008进行验证和可复制的示例。
aka-> 实际上,即使您只是向数据库发送一条语句,也要始终包含终止符。
分号并不总是在复合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)