Anda dapat (ab) menggunakan MERGE
dengan OUTPUT klausa.
MERGE dapat INSERT , UPDATE dan DELETE baris. Dalam kasus kami, kami hanya perlu INSERT .1=0 selalu salah, jadi NOT MATCHED BY TARGET bagian selalu dieksekusi. Secara umum, mungkin ada cabang lain, lihat dokumen.WHEN MATCHED biasanya digunakan untuk UPDATE;WHEN NOT MATCHED BY SOURCE biasanya digunakan untuk DELETE , tapi kita tidak membutuhkannya di sini.
Bentuk rumit dari MERGE setara dengan INSERT sederhana , tetapi tidak seperti INSERT sederhana OUTPUT-nya klausa memungkinkan untuk merujuk ke kolom yang kita butuhkan. Ini memungkinkan untuk mengambil kolom dari tabel sumber dan tujuan sehingga menyimpan pemetaan antara ID lama dan baru.
MERGE INTO [dbo].[Test]
USING
(
SELECT [Data]
FROM @Old AS O
) AS Src
ON 1 = 0
WHEN NOT MATCHED BY TARGET THEN
INSERT ([Data])
VALUES (Src.[Data])
OUTPUT Src.ID AS OldID, inserted.ID AS NewID
INTO @New(ID, [OtherID])
;
Mengenai pembaruan Anda dan mengandalkan urutan IDENTITY yang dihasilkan nilai.
Dalam kasus sederhana, ketika [dbo].[Test] memiliki IDENTITY kolom, lalu INSERT dengan ORDER BY akan menjamin bahwa IDENTITY . yang dihasilkan nilai akan berada dalam urutan yang ditentukan. Lihat poin 4 di Jaminan pemesanan di SQL Server . Ingat, ini tidak menjamin urutan fisik baris yang disisipkan, tetapi menjamin urutan IDENTITY nilai dihasilkan.
INSERT INTO [dbo].[Test] ([Data])
SELECT [Data]
FROM @Old
ORDER BY [RowID]
Tapi, ketika Anda menggunakan OUTPUT klausa:
INSERT INTO [dbo].[Test] ([Data])
OUTPUT inserted.[ID] INTO @New
SELECT [Data]
FROM @Old
ORDER BY [RowID]
baris dalam OUTPUT aliran tidak dipesan. Setidaknya, secara tegas, ORDER BY dalam kueri berlaku untuk INSERT utama operasi, tetapi tidak ada yang mengatakan apa urutan OUTPUT . Jadi, saya tidak akan mencoba mengandalkan itu. Gunakan MERGE atau tambahkan kolom tambahan untuk menyimpan pemetaan antar ID secara eksplisit.