sql >> Database >  >> RDS >> Sqlserver

Combineer OUTPUT insert.id met waarde uit geselecteerde rij

U kunt (ab)gebruiken MERGE met OUTPUT clausule.

MERGE kan INSERT , UPDATE en DELETE rijen. In ons geval hoeven we alleen INSERT .1=0 is altijd onwaar, dus de NOT MATCHED BY TARGET deel wordt altijd uitgevoerd. In het algemeen kunnen er andere branches zijn, zie docs.WHEN MATCHED wordt meestal gebruikt om UPDATE;WHEN NOT MATCHED BY SOURCE wordt meestal gebruikt om DELETE , maar we hebben ze hier niet nodig.

Deze ingewikkelde vorm van MERGE is gelijk aan eenvoudig INSERT ,maar in tegenstelling tot eenvoudig INSERT zijn OUTPUT clausule maakt het mogelijk om te verwijzen naar de kolommen die we nodig hebben. Hiermee kunnen kolommen worden opgehaald uit zowel bron- als doeltabellen, waardoor een toewijzing tussen oude en nieuwe ID's wordt opgeslagen.

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

Met betrekking tot uw update en vertrouwend op de volgorde van gegenereerde IDENTITY waarden.

In het eenvoudige geval, wanneer [dbo].[Test] heeft IDENTITY kolom, dan INSERT met ORDER BY zal garanderen dat de gegenereerde IDENTITY waarden zouden in de opgegeven volgorde staan. Zie punt 4 in Bestelgaranties in SQL Server . Let wel, het garandeert niet de fysieke volgorde van ingevoegde rijen, maar het garandeert de volgorde waarin IDENTITY waarden worden gegenereerd.

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

Maar wanneer u de OUTPUT . gebruikt clausule:

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

de rijen in de OUTPUT stream zijn niet besteld. Strikt genomen tenminste, ORDER BY in de zoekopdracht is van toepassing op de primaire INSERT operatie, maar er is niets dat zegt wat de volgorde is van de OUTPUT . Dus daar zou ik niet op proberen te vertrouwen. Gebruik ofwel MERGE of voeg een extra kolom toe om de toewijzing tussen ID's expliciet op te slaan.



  1. Is er een manier om toegang te krijgen tot de vorige rijwaarde in een SELECT-instructie?

  2. Rake-taak om alle tabellen in Rails 3 . af te kappen

  3. Waarom hebben we de GLOB-clausule in SQLite nodig?

  4. JPA-selectiequery met tijdstempel en datumvelden kan geen resultaten ophalen