症状
在具有聚集或唯一索引的表上运行更新,并且更新发生在非主要唯一列上时,更改跟踪记录与 update 语句不一致。
例如,假定群集或唯一索引中包含名为“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 |
我 |
空 |
空 |
5639485628 |
1116 |
20 |
D |
空 |
空 |
5639485628 |
当列值从小值更改为较大值 (如将值从 16 更改为 20) 时,会在“I”之前插入“D”。
Sys_change_version |
sys_change_create_version |
sys_change_operation |
sys_change_column |
sys_change_context |
PK_column |
1126 |
32 |
D |
空 |
空 |
5639485628 |
1126 |
33 |
我 |
空 |
空 |
5639485628 |
原因
由于更改跟踪侧表中的删除/插入对之间的排序不正确,因此出现此问题。
解决方法
SQL Server的以下更新中包含此问题的修补程序:
SQL Server 2016 Service Pack 1 的累积更新 9
关于SQL Server生成
SQL Server的每个新版本都包含上一版本中的所有修补程序和安全修补程序。 建议为SQL Server安装最新版本:
状态
Microsoft 已经确认这是一个列于“适用范围”部分的 Microsoft 产品问题。
更多信息
对于启用了更改跟踪的表,当在定义为唯一的非主列上发生更新时,会将两个条目插入到更改跟踪侧表中:每个拆分操作的一个条目:插入和删除。
调用 CHANGETABLE 函 数枚举更改时,这些条目按主键值排序,然后聚合操作。 如果更新插入较低的值,则首先在侧表上运行“I”操作,后跟“D”操作。 这会导致为此行返回错误的操作。 这是因为“I”后跟“D”聚合为“D”。
由于仅在侧表中维护主键值,因此不需要有两个单独的条目。 只要主键列未更新,情况就如此。
此问题已修复为非主要唯一列。 在这种情况下,当发生更新时,只有一行通过将“U”作为更新操作来插入,而不是插入两个具有“D”和“I”的条目。
参考
了解 Microsoft 用于描述软件更新的 术语 。