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.