症狀
當你在一個有叢集或唯一索引的資料表上執行更新,且更新發生在非主唯一欄位時,變更追蹤記錄與更新陳述不一致。
例如,假設一個名為「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 更新中:
Cumulative Update 9 for SQL Server 2016 Service Pack 1
累積更新12 for SQL Server 2014 SP2
關於 SQL Server 建置
每個新的 SQL Server 建置都包含了前一個建置中所有的熱修補與安全修補。 我們建議您安裝最新的 SQL Server 版本:
狀態
Microsoft 已確認這是「適用對象」一節中列出的 Microsoft 產品中的問題。
其他資訊
對於啟用變更追蹤的資料表,當更新發生在定義為唯一且非主欄位時,會在變更追蹤側表中插入兩個項目:分別對應拆分動作 Insert 與 Delete。
當呼叫 CHANGETABLE 函式來列舉變更時,這些條目會依主鍵值排序,然後將操作彙總。 若更新插入較低值,則先在邊桌執行「I」操作,接著執行「D」操作。 這會導致該列回傳錯誤的操作。 這是因為「I」在「D」之後會被彙總成「D」。
由於側表中只保留主要鍵值,因此不必有兩個獨立條目。 只要主鍵欄位沒有更新,這點就成立。
這個問題在非主唯一欄位中已修正。 在這種情況下,當更新發生時,只有一列會入,因為更新操作是「U」,而不是兩個有「D」和「I」的項目。
參考資料
了解 Microsoft 用來描述軟體更新的 術語 。