Hice algunas modificaciones en mi base de datos y necesito migrar los datos antiguos a las nuevas tablas. Para eso, necesito llenar una tabla (ReportOptions) tomando los datos de la tabla original (Practice) y llenar una segunda tabla intermedia (PracticeReportOption).
ReportOption (ReportOptionId int PK, field1, field2...)
Practice (PracticeId int PK, field1, field2...)
PracticeReportOption (PracticeReportOptionId int PK, PracticeId int FK, ReportOptionId int FK, field1, field2...)
Hice una consulta para obtener todos los datos que necesito para pasar de Practice a ReportOptions, pero tengo problemas para llenar la tabla intermedia
--Auxiliary tables
DECLARE @ReportOption TABLE (PracticeId int /*This field is not on the actual ReportOption table*/, field1, field2...)
DECLARE @PracticeReportOption TABLE (PracticeId int, ReportOptionId int, field1, field2)
--First I get all the data I need to move
INSERT INTO @ReportOption
SELECT P.practiceId, field1, field2...
FROM Practice P
--I insert it into the new table, but somehow I need to have the repation PracticeId / ReportOptionId
INSERT INTO ReportOption (field1, field2...)
OUTPUT @ReportOption.PracticeId, --> this is the field I don't know how to get
inserted.ReportOptionId
INTO @PracticeReportOption (PracticeId, ReportOptionId)
SELECT field1, field2
FROM @ReportOption
--This would insert the relationship, If I knew how to get it!
INSERT INTO @PracticeReportOption (PracticeId, ReportOptionId)
SELECT PracticeId, ReportOptionId
FROM @ReportOption
Si pudiera hacer referencia a un campo que no está en la tabla de destino en la cláusula OUTPUT, sería genial (creo que no puedo, pero no estoy seguro). ¿Alguna idea sobre cómo lograr mi necesidad?
sql
sql-server
Alejandro B.
fuente
fuente
OUTPUT
cláusula. Entonces, incluso si no proporciona un valor para una columna determinada en suINSERT
declaración, aún puede especificar esa columna en laOUTPUT
cláusula. Sin embargo, no puede devolver columnas o variables SQL de otras tablas.Respuestas:
Puede hacer esto usando en
MERGE
lugar de insertar:así que reemplaza esto
con
La clave es usar un predicado que nunca será verdadero (1 = 0) en la condición de búsqueda de combinación, por lo que siempre realizará la inserción, pero tendrá acceso a los campos en las tablas de origen y destino.
Aquí está el código completo que usé para probarlo:
Más lectura, y la fuente de todo lo que sé sobre el tema está aquí.
fuente
Quizás alguien que use MS SQL Server 2005 o versiones anteriores encuentre útil esta respuesta.
MERGE funcionará solo para SQL Server 2008 o superior. Para descansar, encontré otra solución que le dará la posibilidad de crear tipos de tablas de mapeo.
Así es como se verá la resolución para SQL 2005:
El truco principal es que estamos llenando la tabla de mapeo dos veces con datos ordenados de la tabla de origen y destino. Para obtener más detalles aquí: Fusionar datos insertados usando OUTPUT en SQL Server 2005
fuente
Output
misInsert
's de una salidaTable
que incluye unIdentity
valor de la metaTable
con un no-Insert
valor -ed (PK) de la fuenteTable
(por cierto, por lo que pude entonces (en un lote diferente) el uso que la producciónTable
para poblar unaColumn
de la fuenteTable
con elIdentity
valor). Sin aMerge
, imagino que tendría que: a) comenzarTransaction
, b) obtener el siguienteIdentity
, c) Insertar en tempTable
con calculadoIdentity
, d) establecerIdentity_Insert
, e)Insert
en objetivoTable
desde tempTable
, f) borrarIdentity_Insert
.