Sie können MERGE
(ab)verwenden
mit OUTPUT
Klausel.
MERGE
kann INSERT
, UPDATE
und DELETE
Reihen. In unserem Fall brauchen wir nur INSERT
.1=0 ist immer falsch, also NOT MATCHED BY TARGET
Teil wird immer ausgeführt. Im Allgemeinen könnte es andere Branches geben, siehe docs.WHEN MATCHED
wird normalerweise zum UPDATE
verwendet;WHEN NOT MATCHED BY SOURCE
wird normalerweise zum DELETE
verwendet , aber wir brauchen sie hier nicht.
Diese verschlungene Form von MERGE
entspricht einfach INSERT
, aber im Gegensatz zu einfachem INSERT
sein OUTPUT
-Klausel ermöglicht es, auf die Spalten zu verweisen, die wir benötigen. Sie ermöglicht das Abrufen von Spalten sowohl aus Quell- als auch aus Zieltabellen, wodurch eine Zuordnung zwischen alten und neuen IDs eingespart wird.
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])
;
In Bezug auf Ihr Update und das Vertrauen auf die Reihenfolge der generierten IDENTITY
Werte.
Im einfachen Fall, wenn [dbo].[Test]
hat IDENTITY
Spalte, dann INSERT
mit ORDER BY
wird garantieren, dass die generierte IDENTITY
Werte wären in der angegebenen Reihenfolge. Siehe Punkt 4 in Ordnen von Garantien in SQL Server . Wohlgemerkt, es garantiert nicht die physische Reihenfolge der eingefügten Zeilen, aber es garantiert die Reihenfolge, in der IDENTITY
Werte generiert werden.
INSERT INTO [dbo].[Test] ([Data])
SELECT [Data]
FROM @Old
ORDER BY [RowID]
Aber wenn Sie den OUTPUT
verwenden Klausel:
INSERT INTO [dbo].[Test] ([Data])
OUTPUT inserted.[ID] INTO @New
SELECT [Data]
FROM @Old
ORDER BY [RowID]
die Zeilen in OUTPUT
Stream sind nicht bestellt. Streng genommen zumindest ORDER BY
in der Abfrage gilt für den primären INSERT
Operation, aber es gibt dort nichts, was die Reihenfolge der OUTPUT
aussagt . Darauf würde ich mich also nicht verlassen. Verwenden Sie entweder MERGE
oder fügen Sie eine zusätzliche Spalte hinzu, um die Zuordnung zwischen IDs explizit zu speichern.