次のようなクエリを使用してレコードを挿入しています。
insert into tbl_xyz select field1 from tbl_abc
ここで、挿入されたレコードの新しく生成された IDENTITY 値を取得したいと思います。最小量のロックと最大の信頼性でこれを行うにはどうすればよいですか?
次のようなクエリを使用してレコードを挿入しています。
insert into tbl_xyz select field1 from tbl_abc
ここで、挿入されたレコードの新しく生成された IDENTITY 値を取得したいと思います。最小量のロックと最大の信頼性でこれを行うにはどうすればよいですか?
この情報は、OUTPUT句を使用して取得できます。
情報を一時ターゲット テーブルまたはビューに出力できます。
次に例を示します。
DECLARE @InsertedIDs TABLE (ID bigint)
INSERT into DestTable (col1, col2, col3, col4)
OUTPUT INSERTED.ID INTO @InsertedIDs
SELECT col1, col2, col3, col4 FROM SourceTable
その後、挿入された ID のテーブル InsertedIDs を照会できます。
@@IDENTITY は最後に挿入された IDENTITY 値を返すため、2 つの問題が考えられます。
@@IDENTITY の値が変更される可能性があるため、table_xyz に挿入するときに実行されるトリガーに注意してください。
tbl_abc には複数の行がありますか。その場合、@@IDENTITY は最後の行の ID 値のみを返します
問題 1 は @@IDENTITY の代わりに SCOPE__IDENTITY() を使用することで解決できます 問題 2 は解決が困難です。tbl_abc の field1 は tbl_xyz 内の一意のレコードを定義しますか? その場合、ID 列を使用して table_xyz からデータを再選択できます。CURSORS を使用する他のソリューションがありますが、これらは遅くなります。
SELECT @@IDENTITY
これは私が以前にやった方法です。ただし、これが投稿の後半を満たすかどうかはわかりません。
編集
このリンクも見つかりましたが、同じか
どうかはわかりません...複数のレコードを挿入してID値を取得するにはどうすればよいですか?
私の知る限り、同じスクリプト内で直接 SQL を使用してこれを行うことは実際にはできません。ただし、INSERT トリガーを作成することはできます。さて、私はトリガーが嫌いですが、それはそれを行う1つの方法です.
何をしようとしているのかによって、行を最初に一時テーブルまたはテーブル変数に挿入し、結果セットをそのように処理することができます。リンクできるユニークなコラムがあることを願っています。
テーブルをロックし、最大キーを取得し、行を挿入してから、再度最大キーを取得して範囲を指定することもできます。
引き金:
--Use the Inserted table. This conaints all of the inserted rows.
SELECT * FROM Inserted
一時テーブル:
insert field1, unique_col into #temp from tbl_abc
insert into tbl_xyz (field1, unique_col) select field1, unique_col from tbl_abc
--This could be an update, or a cursor, or whatever you want to do
SELECT * FROM tbl_xyz WHERE EXISTS (SELECT top 1 unique_col FROM #temp WHERE unique_col = tbl_xyz.unique_col)
キーレンジ:
Declare @minkey as int, @maxkey as int
BEGIN TRANS --You have to lock the table for this to work
--key is the name of your identity column
SELECT @minkey = MAX(key) FROM tbl_xyz
insert into tbl_xyz select field1 from tbl_abc
SELECT @maxkey = MAX(key) FROM tbl_xyz
COMMIT Trans
SELECT * FROM tbl_xyz WHERE key BETWEEN @minkey and @maxkey