整数 PK 值增加 1 不会引发重复键错误。为什么?

Nev*_*ing 3 sql-server

正如标题中所述,我想知道为什么以下代码段会记录失败并显示重复键错误。作为以下测试的结果,很明显,更新不会在每一行之后检查重复性。里面会发生什么?这只是 SQL Server 特定行为的标准的一部分吗?谢谢!

DECLARE @T TABLE(
    x INT PRIMARY KEY
);

INSERT INTO @T VALUES (1)
INSERT INTO @T VALUES (2)

UPDATE @T SET x = x + 1;

-- DUPLICATE KEY ERROR EXPECTED.

SELECT * FROM @T;

--- VALUES HAVE BEEN INCREMENTED. NO ERROR THROWN.
Run Code Online (Sandbox Code Playgroud)

ype*_*eᵀᴹ 6

检查(关于UNIQUEPRIMARY KEY其他NOT NULLCHECK约束)在整个UPDATE语句完成后完成。这是 SQL 中的预期行为。操作/语句是在(行)集合上执行的,而不是单独在每一行上执行。(*)

而对于NOT NULLCHECK约束,检查是在每一行更改之后还是在整个语句之后进行都没有关系,对于唯一约束(UNIQUEPRIMARY KEY),它确实很重要。

事实上,SQL 标准有 2 个选项。检查要么在语句之后(当约束为NOT DEFERRABLE)或什至在事务结束时(当约束为DEFERRABLE)并且语句是事务的一部分时完成。

SQL-Server 只支持NOT DEFERRABLE约束,所以检查是在每个语句之后而不是在事务结束时。


(*)
也许您已经习惯了 MySQL,它显示了这种非标准行为,在每行更新(或插入)后检查约束。请参阅更新失败的SQL-Fiddle(如果您将 DBMS 从 SQL-Server 更改为MySQL。)