Você pode (ab) usar
MERGE
com OUTPUT cláusula. MERGE pode INSERT , UPDATE e DELETE linhas. No nosso caso, precisamos apenas INSERT .1=0 é sempre falso, então NOT MATCHED BY TARGET parte é sempre executada. Em geral, pode haver outras ramificações, veja docs.WHEN MATCHED geralmente é usado para UPDATE;WHEN NOT MATCHED BY SOURCE é normalmente usado para DELETE , mas não precisamos deles aqui. Esta forma complicada de
MERGE é equivalente ao simples INSERT ,mas ao contrário do simples INSERT sua OUTPUT A cláusula permite fazer referência às colunas que precisamos. Permite recuperar colunas das tabelas de origem e destino, salvando assim um mapeamento entre os IDs antigos e novos. 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])
;
Em relação à sua atualização e contando com a ordem de
IDENTITY gerada valores. No caso simples, quando
[dbo].[Test] tem IDENTITY coluna e, em seguida, INSERT com ORDER BY vai garantir que a IDENTITY gerada valores estariam na ordem especificada. Consulte o ponto 4 em Garantias de pedidos no SQL Server . Lembre-se, ele não garante a ordem física das linhas inseridas, mas garante a ordem em que IDENTITY valores são gerados. INSERT INTO [dbo].[Test] ([Data])
SELECT [Data]
FROM @Old
ORDER BY [RowID]
Mas, quando você usa o
OUTPUT cláusula:INSERT INTO [dbo].[Test] ([Data])
OUTPUT inserted.[ID] INTO @New
SELECT [Data]
FROM @Old
ORDER BY [RowID]
as linhas no
OUTPUT fluxo não são ordenados. Pelo menos, estritamente falando, ORDER BY na consulta se aplica ao INSERT principal operação, mas não há nada lá que diga qual é a ordem do OUTPUT . Então, eu não tentaria confiar nisso. Ou use MERGE ou adicione uma coluna extra para armazenar explicitamente o mapeamento entre os IDs.