';' 在TSQL语句的开头

All*_* Xu 10 t-sql sql-server

我不时会看到以分号';'开头的SQL Server语句 如下

;WITH cte
     AS (SELECT ROW_NUMBER() OVER (PARTITION BY Col1, Col2, Col3 
                                       ORDER BY ( SELECT 0)) RN
         FROM   #MyTable)
DELETE FROM cte
WHERE  RN > 1
Run Code Online (Sandbox Code Playgroud)

另一个例子是 ;THROW

为什么确实存在';' TSQL语句的开头

更新1:

请注意,我在询问';' 在陈述的开头.这个问题与此问题不重复

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

更新2:

@MartinSmith的回答很有道理.

为了确保我们对这篇文章有完整的答案,请考虑这篇受人尊敬的文章:

http://www.sommarskog.se/error_handling/Part1.html#jumpTHROW

在这一点上你可能会对自己说:他必须拉我的腿,微软真的称之为命令;那么?不仅仅是那个吗?没错,如果您在联机丛书中查找,则没有领先的分号.但分号必须在那里.正式地说,它是前一个语句的终结符,但它是可选的,并且远非每个人都使用分号来终止它们的T-SQL语句.

我同意@MartinSmith的答案,但似乎这件事情正处于一些非常极端的程度.

通常,在存储过程中,THROW是其自己的行的声明.SQL开发人员不仅仅是合并这样的SQL行而错过了分号.

对我来说,人们更有可能意外地放弃一张桌子,而不是将"THROW"语句与另一行TSQL混合

在上面的引文中解释的情况是极端且罕见的吗?或者我在这里错过了一点?

Mar*_*ith 13

应该是在不在他们面前的陈述之后.但是在TSQL的大多数情况下,语句中的终止半冒号在实践中当前是可选的(尽管技术上推荐使用带分号的Transact-SQL语句结束)并且不强制存在终止半冒号的语句.

一个例外是MERGE语句(确实需要一个终止的半冒号)以及前面WITH或后面的语句THROW

因此,对于StackOverflow上的答案,如果OP(或未来的读者)将其粘贴到某些现有批次的中间,并且在前面的语句中没有所需的半冒号,然后抱怨它不起作用,这是一个有点防御性的做法他们收到以下错误.

关键字'with'附近的语法不正确.如果此语句是公用表表达式,xmlnamespaces子句或更改跟踪上下文子句,则必须以分号终止先前的语句.

在这种情况下,该前面的语句以分号结束的附加一个没有任何伤害.它只是被视为一个空洞的陈述.

尽管在多语句无效的上下文中使用CTE,但这种做法本身可能会导致问题.例如,在WITH此之前插入分号会破坏分号.

CREATE VIEW V1
AS
  WITH T(X)
       AS (SELECT 1)
  SELECT *
  FROM   T; 
Run Code Online (Sandbox Code Playgroud)

同样地,THROW盲目地插入前导半结肠也会引起问题.

IF @i IS NULL
;THROW 50000, '@i IS NULL', 1;  
Run Code Online (Sandbox Code Playgroud)

';'附近的语法不正确.

我已修复了您在问题中给出的示例并将其更改为

; 

--Ensure that any immediately preceding statement is terminated with a semicolon above
WITH cte
     AS (SELECT ROW_NUMBER() OVER (PARTITION BY Col1, Col2, Col3 
                                       ORDER BY ( SELECT 0)) RN
         FROM   #MyTable)
DELETE FROM cte
WHERE  RN > 1;
Run Code Online (Sandbox Code Playgroud)