Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Combinez OUTPUT insert.id avec la valeur de la ligne sélectionnée

Vous pouvez (ab)utiliser MERGE avec OUTPUT clause.

MERGE peut INSERT , UPDATE et DELETE Lignes. Dans notre cas, nous n'avons qu'à INSERT .1=0 est toujours faux, donc le NOT MATCHED BY TARGET part est toujours exécutée.En général, il pourrait y avoir d'autres branches, voir docs.WHEN MATCHED est généralement utilisé pour UPDATE;WHEN NOT MATCHED BY SOURCE est généralement utilisé pour DELETE , mais nous n'en avons pas besoin ici.

Cette forme alambiquée de MERGE équivaut à un simple INSERT , mais contrairement au simple INSERT sa OUTPUT La clause permet de faire référence aux colonnes dont nous avons besoin. Elle permet de récupérer les colonnes des tables source et destination, économisant ainsi un mappage entre les anciens et les nouveaux 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])
;

Concernant votre mise à jour et en vous basant sur l'ordre des IDENTITY générés valeurs.

Dans le cas simple, lorsque [dbo].[Test] a IDENTITY colonne, puis INSERT avec ORDER BY va garantir que l'IDENTITY généré les valeurs seraient dans l'ordre spécifié. Voir le point 4 dans Commander des garanties dans SQL Server . Attention, cela ne garantit pas l'ordre physique des lignes insérées, mais cela garantit l'ordre dans lequel IDENTITY les valeurs sont générées.

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

Mais, lorsque vous utilisez le OUTPUT clause :

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

les lignes dans le OUTPUT flux ne sont pas ordonnés. Au moins, à proprement parler, ORDER BY dans la requête s'applique au INSERT principal opération, mais rien n'indique quel est l'ordre de la OUTPUT . Donc, je n'essaierais pas de me fier à cela. Soit utiliser MERGE ou ajoutez une colonne supplémentaire pour stocker explicitement le mappage entre les ID.