共用方式為


SR0008:考慮使用 SCOPE_IDENTITY 來代替 @@IDENTITY

RuleId

SR0008

分類

Microsoft.Design

中斷變更

中斷

原因

您的程式碼包含 @@IDENTITY 呼叫。

規則描述

由於 @@IDENTITY 是全域識別值,因此可能已在目前範圍外更新,並已取得未預期的值。 觸發程序包括複寫使用的巢狀觸發程序,可以在目前範圍外更新 @@IDENTITY。

如何修正違規

若要解決此問題,您必須將 @@IDENTITY 的參考取代為 SCOPE_IDENTITY,後者會傳回使用者陳述式範圍內最新的識別值。

隱藏警告的時機

如果您確定在沒有其他處理序可能已更新 @@IDENTITY 值的情況下,所使用的陳述式是使用 @@IDENTITY,則您可能會隱藏這個警告。 不過,強烈建議您解決警告而不要隱藏它,因為 SCOPE_IDENTITY 會提供所要的值,而不會有發生非預期變更的風險。

範例

在第一個範例中,將資料插入資料表的預存程序是使用 @@IDENTITY。 接著會發行資料表進行合併式複寫,這項作業會將觸發程序加入至發行的資料表中。 因此,@@IDENTITY 可從插入作業將值傳回複寫系統資料表中,而不是從插入作業傳回使用者資料表中。

Sales.Customer 資料表具有 29483 的最大識別值。 如果將資料列插入資料表 @@IDENTITY 和 SCOPE_IDENTITY() 就會傳回不同的值。 SCOPE_IDENTITY() 會從插入作業將值傳回使用者資料表中,而 @@IDENTITY 則是從插入作業將值傳回複寫系統資料表中。

第二個範例將顯示如何使用 SCOPE_IDENTITY() 存取插入的識別值並解決警告。

CREATE PROCEDURE [dbo].[ProcedureWithWarning]
@param1 INT, 
@param2 NCHAR(1),
@Param3 INT OUTPUT
AS
BEGIN
INSERT INTO Sales.Customer ([TerritoryID],[CustomerType]) VALUES (@param1,@param2);

SELECT @Param3 = @@IDENTITY
END

CREATE PROCEDURE [dbo].[ProcedureFixed]
@param1 INT, 
@param2 NCHAR(1),
@param3 INT OUTPUT
AS
BEGIN
INSERT INTO Sales.Customer ([TerritoryID],[CustomerType]) VALUES (@param1,@param2);

SELECT @Param3 = SCOPE_IDENTITY()
END

請參閱

概念

分析資料庫程式碼以改善程式碼品質