挿入された行のIDを取得する最良の方法は?

挿入された行の「IDENTITY」を取得するには、どのような方法がありますか?

IDENTITYIDENT_CURRENTSCOPE_IDENTITY`については知っていますが、それぞれの長所と短所を理解していません。

どなたか、その違いと、どのような場合にそれぞれを使用すべきかを説明してください。

ソリューション
  • @IDENTITYは、現在のセッションの任意のテーブルに対して生成された最後のID値を、すべてのスコープにわたって返します。 **ここで注意しなければならないのは、スコープを越えているということです。 現在のステートメントではなく、トリガーから値を取得することもできます。

  • SCOPE_IDENTITY()は、現在のセッションと現在のスコープ内の任意のテーブルに対して生成された最後のID値を返します。 一般的に使用したいものです。

  • IDENT_CURRENT('tableName') は、任意のセッション、任意のスコープの特定のテーブルに対して生成された最後のID値を返します。 これにより、上記の2つが必要としているものではない場合(非常に稀)に、どのテーブルから値を得るかを指定することができます。 また、@Guy Starbuckが述べているように、"You could use this if you want to get the current IDENTITY value for a table that you have been inserted a record into." (レコードを挿入していないテーブルの現在のIDENTITY値を取得したい場合に、これを使用することができます)。

  • INSERT文の[OUTPUT`句]5を使うと、その文で挿入されたすべての行にアクセスできます。 特定のステートメントにスコープされているので、上記の他の関数よりも わかりやすい です。 しかし、これは少し冗長で(テーブル変数/テンプテーブルに挿入し、それをクエリする必要があります)、ステートメントがロールバックされるエラーシナリオでも結果が得られます。 とはいえ、クエリが並列実行プランを使用している場合、これは(並列処理をオフにしない限り)IDを取得するための唯一の保証された方法です。しかし、この方法はトリガーの前に実行されるため、トリガーで生成された値を返すためには使用できません。

解説 (14)

MSDNを参照してください。

@@IDENTITY、SCOPE_IDENTITY、IDENT_CURRENTは、テーブルのIDENTITY列に最後に挿入された値を返すという点で類似した関数です。

@@IDENTITY および SCOPE_IDENTITY は、現在のセッションの任意のテーブルで生成された最後の ID 値を返します。ただし、SCOPE_IDENTITY は現在のスコープ内でのみ値を返しますが、@@IDENTITY は特定のスコープに限定されません。

IDENT_CURRENTは、スコープやセッションによる制限はなく、指定されたテーブルに限定されます。IDENT_CURRENT は、任意のセッション、任意のスコープで、特定のテーブルに対して生成された ID 値を返します。詳細については、「IDENT_CURRENT」を参照してください。

  • IDENT_CURRENTは、テーブルを引数として取る関数です。
  • IDENTITY]3は、テーブルにトリガがある場合には、混乱した結果を返すことがあります。
  • SCOPE_IDENTITY]4は、ほとんどの場合、あなたのヒーローです。
解説 (0)

IDENTITYは、現在のSQL接続を使用して最後に挿入されたIDです。 これは、新しいレコードのために挿入されたIDが必要なだけで、その後に行が追加されたかどうかは気にしない、挿入ストアド・プロシージャから返すのに適した値です。

SCOPE_IDENTITYは、現在のSQL接続を使用して、現在のスコープで最後に挿入されたIDです。つまり、挿入後にトリガに基づいて2番目のIDが挿入された場合、それはSCOPE_IDENTITYには反映されず、実行した挿入のみが反映されます。正直なところ、これを使う理由はありません。

IDENT_CURRENT(tablename)は、接続やスコープに関係なく、最後に挿入されたIDです。 これは、レコードを挿入していないテーブルの現在のIDENTITY値を取得したい場合に使用できます。

解説 (2)