mar*_*ark 7 sql-server sql-server-2012
首先创建两个表:
CREATE TABLE xyz (Id INT)
CREATE TABLE abc (Id INT)
Run Code Online (Sandbox Code Playgroud)
请注意以下 SQL 代码:
DELETE FROM abc
BEGIN TRAN
EXEC('
INSERT INTO xyz VALUES (1),(2)
DECLARE @x INT = (SELECT Id FROM xyz)
')
INSERT INTO abc VALUES (1)
COMMIT
SELECT * FROM abc
Run Code Online (Sandbox Code Playgroud)
运行它会输出以下错误:
Msg 512, Level 16, State 1, Line 3
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Run Code Online (Sandbox Code Playgroud)
而且没有结果。一切都在预料之中。
现在让我们通过替换xyz)
为将错误更改为语法错误xyz
。这是错误:
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near 'xyz'.
Run Code Online (Sandbox Code Playgroud)
但这一次有结果:
为什么?到底是怎么回事?
该行为取决于SET XACT_ABORT,并在链接文章的以下引用中进行了解释。
当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句引发运行时错误,则整个事务将终止并回滚。
当 SET XACT_ABORT 为 OFF 时,在某些情况下,只会回滚引发错误的 Transact-SQL 语句,并且事务继续处理。根据错误的严重程度,即使 SET XACT_ABORT 为 OFF,整个事务也可能会回滚。关是默认设置。
您可以通过指定以下内容来控制第一个示例的行为:
SET XACT_ABORT ON
Run Code Online (Sandbox Code Playgroud)
在脚本的顶部,您不会得到结果。如果您指定,您确实会得到您描述的结果SET XACT_ABORT OFF
。
不同行为的原因是第二个示例“替换xyz)
为xyz
”包含一个语法错误,即解析 EXEC 批处理,发现语法错误并且批处理未运行。EXEC 是一个单独的批处理(这就是您不能在 EXEC 之外定义变量并在内部引用它们的原因)并且处理将继续处理事务的其余部分。
对于第一个示例“ (SELECT Id FROM xyz)
”,这是有效的语法,因此批处理可以正确解析。该错误仅在运行时发现,如果 则处理继续,如果 则SET XACT_ABORT OFF
停止SET XACT_ABORT ON
。
归档时间: |
|
查看次数: |
673 次 |
最近记录: |