Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Kombinieren Sie OUTPUT inserted.id mit dem Wert aus der ausgewählten Zeile

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.