sql >> Databasteknik >  >> RDS >> Sqlserver

Kombinera OUTPUT inserted.id med värde från vald rad

Du kan (ab)använda MERGE med OUTPUT klausul.

MERGE kan INSERT , UPDATE och DELETE rader. I vårt fall behöver vi bara INSERT .1=0 är alltid false, så NOT MATCHED BY TARGET del exekveras alltid. I allmänhet kan det finnas andra grenar, se dokument.WHEN MATCHED används vanligtvis för att UPDATE;WHEN NOT MATCHED BY SOURCE används vanligtvis för att DELETE , men vi behöver dem inte här.

Denna invecklade form av MERGE motsvarar enkel INSERT , men till skillnad från enkla INSERT dess OUTPUT klausulen gör det möjligt att referera till de kolumner som vi behöver. Den gör det möjligt att hämta kolumner från både käll- och destinationstabeller och sparar därmed en mappning mellan gamla och nya 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])
;

Angående din uppdatering och att förlita sig på ordningen för genererad IDENTITY värden.

I det enkla fallet, när [dbo].[Test] har IDENTITY kolumn och sedan INSERT med ORDER BY kommer garantera att den genererade IDENTITY värdena skulle vara i angiven ordning. Se punkt 4 i Beställningsgarantier i SQL Server . Tänk på att det inte garanterar den fysiska ordningen för infogade rader, men det garanterar ordningen i vilken IDENTITY värden genereras.

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

Men när du använder OUTPUT klausul:

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

raderna i OUTPUT strömmen är inte beställd. Åtminstone, strängt taget, ORDER BY i frågan gäller den primära INSERT operation, men det finns inget där som säger vad som är ordningen för OUTPUT . Så jag skulle inte försöka lita på det. Använd antingen MERGE eller lägg till en extra kolumn för att explicit lagra mappningen mellan ID:n.



  1. Oracle-fråga för att hitta alla förekomster av ett tecken i en sträng

  2. mysql unika nummergenerering

  3. Är det bättre att använda ett tomt värde som '' eller som NULL?

  4. Hur man använder GROUP_CONCAT-funktionen på MSSQL