あなたが聞きたいと思われる答えではないことは知っていますが、答えはを使用することSCOPE_IDENTITY()
です。あなたが考えている問題(どのテーブルでもそうなるでしょう)は、なぜ私たちがSCOPE_IDENTITY()
の代わりに使うのかということです@@IDENTITY
。IDENTITY
列のあるテーブルがあり、そのテーブルに挿入トリガーがあり、それ自体が列のあるテーブルに挿入される場合を考えてみIDENTITY
ます。
CREATE TABLE dbo.Log(LogID INT IDENTITY(100,1), FooID INT);
CREATE TABLE dbo.Foo(FooID INT IDENTITY(1,1), name VARCHAR(32));
GO
CREATE TRIGGER dbo.Foo_Insert
ON dbo.Foo
FOR INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.Log(FooID) SELECT FooID FROM inserted;
END
GO
さて、あなたの状況は、挿入後にIDを取得するための信頼できる方法が必要な場合です。SCOPE_IDENTITY()
これは、スコープに制限されているため、スコープに制限されていないためです(つまり、スコープではなく、トリガーのスコープで発生した@@IDENTITY
最後に発行されたものを取得します。IDENTITY
INSERT dbo.Foo(name) SELECT 'Bob';
SELECT
@@IDENTITY,
SCOPE_IDENTITY();
結果:
---- ----
100 1
複数の行を挿入する場合は、どちらSCOPE_IDENTITY()
も使用しないでください。@@IDENTITY
これを行う方法は、OUTPUT
句を使用することです。まず、トリガーをドロップしましょう。
DROP TRIGGER dbo.Foo_Insert;
次に、複数行の挿入をテストしてみましょう。
INSERT dbo.Foo(name)
OUTPUT inserted.FooID, inserted.name
SELECT 'Frank' UNION ALL SELECT 'Jim';
結果:
FooID name
----- -----
2 Frank
3 Jim
条件付き挿入がある場合、違いはありません。持っているテーブルを維持しながら、このコードを2回試してみましょう。
DECLARE @table SYSNAME;
SET @table = N'Log';
IF @table = N'Log'
BEGIN
INSERT dbo.Log(FooID) SELECT 10;
END
IF @table = N'Foo'
BEGIN
INSERT dbo.Foo(name) SELECT 'Tom';
END
SELECT SCOPE_IDENTITY();
結果:
----
101
でもう一度試してみましょうN'Foo'
:
DECLARE @table SYSNAME;
SET @table = N'Foo';
IF @table = N'Log'
BEGIN
INSERT dbo.Log(FooID) SELECT 10;
END
IF @table = N'Foo'
BEGIN
INSERT dbo.Foo(name) SELECT 'Tom';
END
SELECT SCOPE_IDENTITY();
結果:
----
4
それよりも複雑な場合(たとえば、複数のテーブルに挿入する場合)、次のようなことができます。
IF <some conditional>
BEGIN
INSERT dbo.sometable ...
SET @somevar = SCOPE_IDENTITY();
END
IF <some other conditional>
BEGIN
INSERT dbo.some_other_table ...
SET @some_other_var = SCOPE_IDENTITY();
END
なぜこれが機能しないと思うのかわかりません。また、機能することを納得させるために、なぜこの長さに行かなければならないのかわかりません。繰り返しになりますが、これが機能しない例(または、干渉すると思われる「任意のテーブル」)を示すと、コメントできる可能性があります。現状では、あなたの意見はSCOPE_IDENTITY()
あなたが聞いたことに基づいているように思えます@@IDENTITY
。これらの仮定は、自分自身を証明または反証するのは非常に簡単です。
余談ですIDENT_CURRENT
が、この会話では言及されるべきではありません。並行アクティビティに使用することはまったく安全ではありません。私に関する限り、聞いたことがないふりをする必要があります。トリガーの外側から、トリガーの内側で生成された@@IDENTITY
ものを本当にキャプチャしたい場合を除いて、これの有効な使用法は考えられません。IDENTITY