徵兆
當您使用SCOPE_IDENTITY () 或@@IDENTITY函數來取回 插入身分識別資料行的值時,您可能會注意到這些函數有時候會返回不正確的值。 只有在查詢使用平行執行計畫時,才能發生此問題。 若要進一步瞭解如何判斷查詢是否要使用平行執行計畫,請參閱下列 Microsoft 下載技術文章中的內部查詢平行性一節:
原因
Microsoft 已確認這是本文開頭所列的 Microsoft 產品中的問題。
解決方案
累積更新資訊
SQL Server 2008 R2 Service Pack 1
此問題的修正程式最初是在 SQL Server 2008 R2 Service Pack 1 的累積更新 5 中發行。 若要進一步瞭解如何取得此累積更新套件,請按一下下列文章編號以在 Microsoft 知識庫中查看文章:
2659694SQL Server 2008 R2 Service Pack 1 的累積更新套件 5
附註 由於建立是累加的,因此每個新的修正版本都包含所有 Hotfix,以及先前 SQL Server 2008 R2 修正版本中包含的所有安全性修正程式。 建議您考慮使用包含此 hotfix 的最新修正版本。 如需詳細資訊,請按一下下面的文章編號,檢視「Microsoft 知識庫」中的文章:
2567616SQL Server 2008 R2 Service Pack 1 發行後發佈的 SQL Server 2008 R2 版本
因應措施
Microsoft 建議您在涉及平行方案時,請勿在查詢中使用這些函數,因為它們不一定可靠。 請改為使用 INSERT 語句 的 OUTPUT 子句來取回身分識別值,如下列範例所示。
使用 OUTPUT 子句的範例:
在 @MyNewIdentityValues表 (myidvalues int)
宣告@A資料表 (ID int 主鍵) 插入 1 @A 1 (的值) 宣告@B識別碼 (主鍵身分識別 (1,1) ,B int not null ) 插入 1 @B 1 (的值) 選取 [RowCount] = @@RowCount, [@@IDENTITY] = @@IDENTITY, [SCOPE_IDENTITY] = SCOPE_IDENTITY () 將統計資料設定檔設定在 插入_ddr_T 輸出 inserted.ID 成@MyNewIdentityValues 選取 b.ID 從 @A 左聯@B b b.ID = 1 左聯@B b2 上的 b2。B = -1 t.T = -1 _ddr_T t 上的左聯點 其中不存在 (從 _ddr_T t2 選取 *,t2.ID = -1) 關閉統計資料設定檔 選取 [RowCount] = @@RowCount, [@@IDENTITY] = @@IDENTITY, [SCOPE_IDENTITY] = SCOPE_IDENTITY () , [IDENT_CURRENT] = IDENT_CURRENT ( _ddr_T ) 選取 * @MyNewIdentityValues 去如果您的情況需要您使用這些函數之一,您可以使用下列其中一種方法來解決此問題。
方法 1:
在查詢中包含下列選項
OPTION (MAXDOP 1)
注意:這可能會損害 SELECT 部分查詢的績效。
方法 2:
將 SELECT 部分的值讀入一組變數 (或單一資料表變數) 然後插入 MAXDOP=1 的目標資料表中。 由於 INSERT 方案不會平行,因此您將獲得正確的語意,但 SELECT 會平行,以達成所需的績效。
方法 3:
執行下列語句,將平行 度 最大值選項設為 1:
sp_configure'最大平行度',1
去
使用重寫重新重配置
去
注意:此方法可能會導致伺服器上發生性能降低。 除非您在測試或暫存環境中評估過這個方法,否則不應該使用此方法。
其他相關資訊
此問題的 Microsoft Connect 錯誤https://docs.microsoft.com/en-us/collaborate/connect-redirect
MAXDOP (並行)https://msdn.microsoft.com/en-us/library/ms181007.aspx