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 時,變更追蹤側表會先接收插入操作,再進行刪除操作。 例如,交易日誌插入列記錄操作會在刪除列操作前接收,或「I」在「D」之前插入。

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時,會在「I」前插入「D」。

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 更新中:

SQL Server 2017 累積更新 8

Cumulative Update 9 for SQL Server 2016 Service Pack 1

累積更新12 for SQL Server 2014 SP2

關於 SQL Server 建置

每個新的 SQL Server 建置都包含了前一個建置中所有的熱修補與安全修補。 我們建議您安裝最新的 SQL Server 版本:

SQL Server 2017 最新累積更新

SQL Server 2016 最新版本

SQL Server 2014 最新累積更新

狀態

Microsoft 已確認這是「適用對象」一節中列出的 Microsoft 產品中的問題。

其他資訊

對於啟用變更追蹤的資料表,當更新發生在定義為唯一且非主欄位時,會在變更追蹤側表中插入兩個項目:分別對應拆分動作 Insert 與 Delete。

當呼叫 CHANGETABLE 函式來列舉變更時,這些條目會依主鍵值排序,然後將操作彙總。 若更新插入較低值,則先在邊桌執行「I」操作,接著執行「D」操作。 這會導致該列回傳錯誤的操作。 這是因為「I」在「D」之後會被彙總成「D」。

由於側表中只保留主要鍵值,因此不必有兩個獨立條目。 只要主鍵欄位沒有更新,這點就成立。

這個問題在非主唯一欄位中已修正。 在這種情況下,當更新發生時,只有一列會入,因為更新操作是「U」,而不是兩個有「D」和「I」的項目。

參考資料

了解 Microsoft 用來描述軟體更新的 術語