查询期间是否会由于行的状态而发生主键冲突?

Will primary key violation ever occur due to state of rows during query?

给定这个带有复合主键的简单 table,

注意: none 的列是自动递增标识 - 所有编号都是手动的

注意 2:这个问题的上下文是在编写更新脚本以在构建时应用,而不是 运行 时。它将静态条目插入到已订购商品的列表中。

我发现以下查询成功地重新编号了一组 select 行(想法是为插入腾出空间,同时保持 id2 作为有序序列)。

update t
set id2 = id2 + 1
where id1 = 2 and id2 > 1

在执行上述查询期间的某个时刻,实际上存在主键违规,但它不会导致我的测试失败,该测试使用 SQL Server 2012.

这让我相信在所有更新之后检查了主键约束。

这是否因 DBMS 而异,或者这是由于 SQL 语句的跨国性质而给定的?

PK自增字段在列内保证唯一,但不一定连续。

然而,绝对不能保证您自己计算的任何类型的 PK 的唯一性。

如果您需要数字 PK,只需设置身份 属性 并让服务器完成它的工作。

重新编号行将是一个非常糟糕的主意,除非数据库处于单用户模式。其他任何事情都只是在自找麻烦,事实上,考虑到数据库的缓存方式,即使您是唯一的用户,我也不相信它会可靠。

实际上在这个查询执行期间没有PK冲突。它是这样工作的(简化):

  1. SQL 服务器搜索 id1 = 2 且 id2 > 1 的行
  2. 计算 id2 + 1
  3. 更新 table

如果您的语句会破坏约束,将在第 3 步检测到。

您可以阅读更多关于逻辑查询处理的内容。规则相同且不依赖于 DBMS,但物理实现不同。