我什么时候应该在SQL Server中使用分号?

时间:2009-04-02 17:11:39

标签: sql-server tsql

在检查Web上的某些代码和SQL Server Management Studio生成的脚本时,我注意到某些语句以分号结束。

那我什么时候应该使用它?

13 个答案:

答案 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

enter image description here

BEGIN TRY
    BEGIN TRAN
    SELECT 1/0 AS CauseAnException;
    COMMIT
END TRY
BEGIN CATCH
    SELECT ERROR_MESSAGE();
    THROW
END CATCH

enter image description here

答案 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)

分号似乎不应与游标操作一起使用:OPENFETCHCLOSEDEALLOCATE。我只是浪费了几个小时。我仔细看了一下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)