Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Combina OUTPUT inserito.id con il valore dalla riga selezionata

Puoi (ab)usare MERGE con OUTPUT clausola.

MERGE può INSERT , UPDATE e DELETE righe. Nel nostro caso dobbiamo solo INSERT .1=0 è sempre falso, quindi NOT MATCHED BY TARGET parte viene sempre eseguita. In generale, potrebbero esserci altri rami, vedere docs.WHEN MATCHED è solitamente usato per UPDATE;WHEN NOT MATCHED BY SOURCE di solito è usato per DELETE , ma non ne abbiamo bisogno qui.

Questa forma contorta di MERGE è equivalente al semplice INSERT ,ma a differenza del semplice INSERT il suo OUTPUT La clausola consente di fare riferimento alle colonne di cui abbiamo bisogno. Consente di recuperare colonne sia dalle tabelle di origine che da quelle di destinazione salvando così una mappatura tra il vecchio e il nuovo ID.

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])
;

Per quanto riguarda il tuo aggiornamento e fare affidamento sull'ordine di IDENTITY generato valori.

Nel caso semplice, quando [dbo].[Test] ha IDENTITY colonna, quindi INSERT con ORDER BY farà garantire che l'IDENTITY generato i valori sarebbero nell'ordine specificato. Vedere il punto 4 in Ordinazione delle garanzie in SQL Server . Intendiamoci, non garantisce l'ordine fisico delle righe inserite, ma garantisce l'ordine in cui IDENTITY vengono generati valori.

INSERT INTO [dbo].[Test] ([Data])
SELECT [Data]
FROM @Old
ORDER BY [RowID]

Ma quando usi OUTPUT clausola:

INSERT INTO [dbo].[Test] ([Data])
OUTPUT inserted.[ID] INTO @New
SELECT [Data]
FROM @Old
ORDER BY [RowID]

le righe in OUTPUT flusso non sono ordinati. Almeno, a rigor di termini, ORDER BY nella query si applica al INSERT principale operazione, ma non c'è nulla che dica qual è l'ordine dell'OUTPUT . Quindi, non proverei a fare affidamento su quello. Usa MERGE oppure aggiungi una colonna aggiuntiva per memorizzare la mappatura tra gli ID in modo esplicito.