@@IDENTITY / SCOPE_IDENTITY() / IDENT_CURRENT(’table_name’) の違い
最後にインサートされた IDENTITY の値を取得するには?
最後にインサートされた IDENTITY の値を取得するのに使える関数には次の3つがあります。
- @@IDENTITY
- SCOPE_IDENTITY()
- IDENT_CURRENT('table_name')
この 3 つ、いったいどのように違って、どれを使えば良いのでしょうか。
@@IDENTITY
@@IDENTITY は現在のセッション内 で、どのテーブルで生成されたかに関わらず、最後にインサートされた IDENTITY の値を返します。
SCOPE_IDENTITY()
SCOPE_IDENTITY は現在のセッション内で、かつ現在のスコープ内で、どのテーブルで生成されたかに関わらず、最後にインサートされた IDENTITY の値を返します。
IDENT_CURRENT('table_name')
IDENT_CURRENT('table_name') はセッションやスコープに関わらず、指定したテーブルに対して最後に生成された IDENTITY の値を返します。
気をつけなければいけないポイント
上で書いたように @@IDENTITY は現在のセッション内 で最後に生成された IDENTITY の値を取得し、現在のスコープ内に限定されません。
ですので、例えば、ストアードプロシジャーを書いていて、上でインサートした親テーブルのキーとなる IDENTITY の値を取得する際に @@IDENTITY を使ってしまうと、もし、親テーブルにトリガーがついていて、他のIDENTITY が設定されているカラムを持つテーブルにインサートをしていた場合、 @@IDENTITY で取得できる値は親テーブルのものではなく、トリガーでインサートした他のテーブルのものになってしまいます。
また、親テーブルの名前を指定して、IDENT_CURRENT('table_name') を使って IDENTITY の値を取得するのも、親テーブルに自分がインサートしてから、IDENT_CURRENT('table_name') を使って値を取得するまでの間に、他のセッションから親テーブルにインサートが行われているかもしれないので危険です。
スコープは関係なくセッション内で最後にインサートされた IDENTITY の値が取りたい、またはセッションに関係なくあるテーブルに最後にインサートされたIDENTITY の値が取りたい、という特別な状況でない限り、ストアードプロシジャー内では SCOPE_IDENTITY() を使用して IDENTITY の値を取得すると良いと思います。