RuleId |
SR0008 |
カテゴリ |
Microsoft.Design |
互換性に影響する変更点 |
なし |
原因
コードに @@IDENTITY 呼び出しが含まれています。
規則の説明
@@IDENTITY はグローバルな ID 値であるため、現在のスコープ外で更新され、予期しない値が取得されることがあります。 レプリケーションで使用される入れ子になったトリガを含め、トリガを行うと、現在のスコープ外で @@IDENTITY を更新することになります。
違反の修正方法
この問題を解決するには、@@IDENTITY への参照を、ユーザー ステートメントのスコープ内で最後に使用した ID 値を返す SCOPE_IDENTITY に置き換える必要があります。
警告を抑制する状況
他の処理で @@IDENTITY の値が更新されていないことが確実なときに @@IDENTITY を使用するステートメントを使用している場合は、この警告を抑制してもかまいません。 ただし、SCOPE_IDENTITY を使用すると目的の値が提供され、予期せず変更される危険性がないため、警告は抑制するのではなく解決することをお勧めします。
使用例
最初の例では、テーブルにデータを挿入するストアド プロシージャに @@IDENTITY が使用されています。 次に、テーブルがマージ レプリケーション用に発行され、発行されたテーブルにトリガが追加されます。 このため、@@IDENTITY は、ユーザー テーブルへの挿入操作の代わりに、レプリケーション システム テーブルへの挿入操作から値を返すことができます。
Sales.Customer テーブルの最大の ID 値は 29483 です。テーブルに行を挿入すると、@@IDENTITY と SCOPE_IDENTITY() は異なる値を返します。 SCOPE_IDENTITY() はユーザー テーブルへの挿入操作から値を返し、@@IDENTITY はレプリケーション システム テーブルへの挿入操作から値を返します。
2 番目の例は、挿入された ID にアクセスするために 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