KB4135113 - 修复:在更新表中具有聚集索引或唯一索引的表期间,更改跟踪记录不一致SQL Server

应用对象
SQL Server 2016 Developer - duplicate (do not use) SQL Server 2016 Enterprise - duplicate (do not use) SQL Server 2016 Enterprise Core - duplicate (do not use) SQL Server 2016 Standard - duplicate (do not use) SQL Server 2014 Service Pack 2 - duplicate (do not use) SQL Server 2014 Developer - duplicate (do not use) SQL Server 2014 Enterprise - duplicate (do not use) SQL Server 2014 Enterprise Core - duplicate (do not use) SQL Server 2014 Standard - duplicate (do not use) SQL Server 2017 Developer on Windows SQL Server 2017 Enterprise on Windows SQL Server 2017 Enterprise Core on Windows SQL Server 2017 Standard on Windows

症状

如果对具有聚集索引或唯一索引的表运行更新,并且更新发生在非主要唯一列上,则更改跟踪记录与更新语句不一致。

例如,假设聚集索引或唯一索引中包含名为“column1”的列。 当列值从较大值更改为较小值 (例如将值从 20 更改为 16) 时,更改跟踪端表会在删除操作之前接收插入操作。 例如,在删除行操作之前收到事务日志插入行记录操作,或在“D”之前插入“I”。

Sys_change_version sys_change_create_version sys_change_operation sys_change_column sys_change_context PK_column
1116 19 I NULL NULL 5639485628
1116 20 D NULL NULL 5639485628

当列值从较小值更改为较大值 (例如将值从 16 更改为 20) 时,“D”将插入到“I”之前。

Sys_change_version sys_change_create_version sys_change_operation sys_change_column sys_change_context PK_column
1126 32 D NULL NULL 5639485628
1126 33 I NULL NULL 5639485628

原因

出现此问题的原因是更改跟踪端表中的删除/插入对之间的顺序不正确。

解决方法

针对SQL Server的以下更新中包括了此问题的修补程序:

2017 SQL Server累积更新 8

SQL Server 2016 Service Pack 1 的累积更新 9

SQL Server 2014 SP2 的累积更新 12

关于SQL Server生成

SQL Server的每个新版本都包含上一版本中的所有修补程序和安全修补程序。 建议为 SQL Server 安装最新版本:

SQL Server 2017 的最新累计更新

2016 SQL Server的最新版本

SQL Server 2014 年的最新累积更新

状态

Microsoft 已确认在 "适用于" 部分中所列的 Microsoft 产品中存在问题。

更多信息

对于已启用更改跟踪的表,当更新在定义为唯一的非主列上时,将两个条目插入到更改跟踪端表中:每个拆分操作的一个条目:插入和删除。

调用 CHANGETABLE 函数来枚举更改时,这些条目按主键值排序,然后聚合操作。 如果更新插入一个较低的值,则首先在侧表中运行“I”操作,然后对“D”操作运行。 这会导致为此行返回不正确的操作。 这是因为“I”后跟“D”聚合为“D”。

由于侧表中只维护主键值,因此不需要有两个单独的条目。 只要主键列未更新,这一点就成立。

此问题已针对非主唯一列修复。 在这种情况下,发生更新时,只有一行是通过将“U”作为更新操作而不是两个具有“D”和“I”的条目来插入的。

参考资料

了解Microsoft用于描述软件更新 的术语