SR0008: @@IDENTITY の代わりに SCOPE_IDENTITY を使用してください

規則 ID

SR0008

分類

Microsoft.Design

互換性に影響する変更点

なし

原因

コードに @@IDENTITY の呼び出しが含まれています。

規則の説明

@@IDENTITY はグローバル ID 値であるため、現在のスコープ外で更新され、予期しない値を取得した可能性があります。 トリガー (レプリケーションで使用される入れ子になったトリガーなど) は、現在のスコープ外の @@IDENTITY を更新できます。

違反の修正方法

この問題を解決するには、@@IDENTITY への参照を SCOPE_IDENTITY に置き換える必要があります。これにより、ユーザー ステートメントのスコープ内で最新の ID 値が返されます。

警告を抑制する状況

他の処理で @@IDENTITY の値が更新されていないことが確実なときに @@IDENTITY を使用するステートメントが使用されている場合は、この警告を抑制できます。 ただし、警告を抑制するのではなく、警告を解決することを強くお勧めします。これは、SCOPE_IDENTITY は予期しない変更を行わずに目的の値を提供するためです。

使用例

最初の例では、@@IDENTITY はデータをテーブルに挿入するストアド プロシージャで使用されています。 その後、テーブルはマージ レプリケーションのために発行され、発行されるテーブルにトリガーが追加されます。 したがって、@@IDENTITY は、ユーザー テーブルへの挿入操作ではなく、レプリケーション システム テーブルへの挿入操作から値を返すことができます。

Sales.Customer テーブルには最大 ID 値 29483 があります。 テーブルに行を挿入すると、@@IDENTITY と SCOPE_IDENTITY() は異なる値を返します。 SCOPE_IDENTITY() はユーザー テーブルへの挿入操作から値を返しますが、@@IDENTITY はレプリケーション システム テーブルへの挿入操作から値を返します。

2 番目の例は、SCOPE_IDENTITY() を使用して、挿入された ID 値にアクセスし、警告を解決する方法を示しています。

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

参照

概念

データベース コードの分析によるコードの品質の向上