我不时会看到以分号';'开头的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
另一个例子是;THROW
为什么确实存在';' TSQL语句的开头
更新1:
请注意我问的是';'在陈述的开头。这个问题与这个问题不重复
When should I use semicolons in SQL Server?
更新2:
@MartinSmith回答很有意义。
为了确保我们对这篇文章有完整的答案,请考虑这篇受人尊敬的文章:
http://www.sommarskog.se/error_handling/Part1.html#jumpTHROW
此时你可能会对自己说:他必须拉我的 微软真的称之为命令; THROW?不是吗 扔?没错,如果你在联机丛书中查找,就没有领先优势 分号。但分号必须在那里。官方说来,它是一个 前一个语句的终止符,但它是可选的,而且远 来自每个人都使用分号来终止他们的T-SQL语句。
我同意@MartinSmith的答案,但似乎这件事情正处于一些非常极端的程度。
通常,在存储过程中,THROW是由其自己的行声明。 SQL开发人员不仅仅是合并这样的SQL行而且会错过分号。
对我而言,人们意外丢弃表格的可能性要大于将“THROW”语句与另一行TSQL混合的可能性
上面的引文中是否解释了一些极端且罕见的事情?或者我在这里错过了一点?
答案 0 :(得分:13)
应该是在他们之前的陈述之后。但在TSQL的大多数情况下,语句中的终止半冒号在实践中目前是可选的(尽管技术上Not ending Transact-SQL statements with a semicolon已被弃用)并且不强制存在终止半冒号的语句。
异常是=IF(B2="","",IF(ISNUMBER(MATCH(B2,keywords!$B$2:$B$5,0)),"Fruit",IF(ISNUMBER(MATCH(B2,keywords!$C$2:$C$5,0)),"Nature",IF(ISNUMBER(MATCH(B2,keywords!$D$2:$D$5,0)),"Vehicle","no match"))))
语句(确实需要终止分号)以及MERGE
或WITH
之前的语句
因此,对于StackOverflow上的答案,如果OP(或未来的读者)将其粘贴到某个现有批次的中间,并且在前面的语句中没有所需的半冒号,然后抱怨,这是一个有点防御性的做法它没有工作,他们收到以下错误。
关键字'附近有'的语法不正确。如果这个陈述是 公用表表达式,xmlnamespaces子句或更改跟踪 context子句,前一个语句必须以a结尾 分号。
如果前面的语句 以分号结尾,则额外的语句不会造成伤害。它只是被视为一个空洞的陈述。
虽然在多语句无效的上下文中使用CTE,但这种做法本身可能会导致问题。例如在THROW
之前插入分号会破坏分号。
WITH
同样地,对于CREATE VIEW V1
AS
WITH T(X)
AS (SELECT 1)
SELECT *
FROM T;
,盲目地插入一个前导的半结肠也会导致问题。
THROW
&#39 ;;'
附近的语法不正确
我修复了the example you give in your question并将其更改为
IF @i IS NULL
;THROW 50000, '@i IS NULL', 1;
答案 1 :(得分:2)
它认为这是为了让解析器有机会弄清楚代码应该做什么。
throw
不是保留关键字,with
可以用作其他语句的一部分。
Transact-SQL中完全有效的语句:
create table throw
(
ID int
)
with(data_compression = none)
请注意,换行符不是解析器用于将一个语句与另一个语句分开的东西。
create
table
throw(ID int)
with (data_compression = none) insert into
throw values(1) select
* from throw
它使用其他一些魔法来弄清楚你真的是这个意思。
create table throw(ID int)
with (data_compression = none);
insert into throw values(1);
select *
from throw;
因此,为了在SQL Server 2005中引入CTE时更容易,并且在SQL Server 2012中添加了throw,则需要使用语句终止符终止前面的语句。
在合并声明结束时要求;
的相同原因。
declare @T table(ID int, Value int);
merge into @T as T
using (values(1, 100)) as S(ID, Value)
on T.ID = S.ID
when matched then
update set Value = S.Value
when not matched then
insert (ID, Value) values(S.ID, S.Value);
更容易解析代码并查看语句实际结束的位置。