2011-05-20 9 views
16

Tengo una tabla artículos (ItemID, nombre, ...) donde ItemID es auto-generada identidadT-SQL: INSERT valor original en la cláusula OUTPUT

Quiero añadir filas en esta tabla DESDE seleccionar en esta misma tabla. Y guarde en la variable de tabla las referencias entre OriginalItemID e NewlyGeneratedID.

por lo que quiero que se vea como la siguiente:

DECLARE @ID2ID TABLE (OldItemID INT, NewItemID INT); 

INSERT INTO Items OUTPUT Items.ItemID, INSERTED.ItemID INTO @ID2ID 
SELECT * FROM Items WHERE Name = 'Cat'; 

PERO Items.ItemID, obviamente, no funciona aquí. ¿Hay alguna solución para hacer que OUTPUT tome el ItemID original de la instrucción SELECT?

+1

Usted tendría que tener algo así como un 'OldItemID' en la tabla de destino que se puede llenar de su valor de "viejo" ItemID. Además: si ese ItemID se genera automáticamente, debe ** especificar explícitamente ** la lista de columnas (todo excepto 'ItemID') tanto en su' INSERT INTO Items ...... 'como en el' SELECT correspondiente (lista de columnas) FROM Items ... 'declaraciones. De lo contrario, seleccionará valores de ID de elemento generados automáticamente "antiguos" e intentará insertarlos en la columna generada automáticamente, lo que probablemente ni siquiera funcionará –

+0

Buen punto. Hay un error en mi ejemplo. De todos modos, el problema persiste. – Evgenyt

Respuesta

19

Si está en SQL Server 2008+, puede usar MERGE para obtener la ID actual y la nueva. La técnica se describe en this question.

Para su ejemplo la declaración podría tener este aspecto:

MERGE Items AS t 
USING (
    SELECT * 
    FROM Items 
    WHERE Name = 'Cat' 
) AS s 
ON 0 = 1 
WHEN NOT MATCHED BY TARGET THEN 
    INSERT (target_column_list) VALUES (source_column_list) 
OUTPUT INSERTED.ItemID, S.ItemID INTO @ID2ID (OldItemID, NewItemID); 
Cuestiones relacionadas