Fiz algumas modificações no meu banco de dados e preciso migrar os dados antigos para as novas tabelas. Para isso, preciso preencher uma tabela (ReportOptions) usando os dados da tabela original (Practice) e preencher uma segunda tabela intermediária (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...)
Fiz uma consulta para obter todos os dados necessários para passar do Practice para o ReportOptions, mas estou tendo problemas para preencher a tabela intermediária
--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
Se eu pudesse fazer referência a um campo que não está na tabela de destino na cláusula OUTPUT, seria ótimo (acho que não posso, mas não tenho certeza). Alguma idéia de como realizar minha necessidade?
sql
sql-server
Alejandro B.
fonte
fonte
OUTPUT
cláusula. Portanto, mesmo se você não fornecer um valor para uma determinada coluna em suaINSERT
instrução, ainda poderá especificar essa coluna naOUTPUT
cláusula No entanto, você não pode retornar variáveis ou colunas SQL de outras tabelas.Respostas:
Você pode fazer isso usando em
MERGE
vez de inserir:então substitua isso
com
A chave é usar um predicado que nunca será verdadeiro (1 = 0) na condição de pesquisa de mesclagem, para que você sempre execute a inserção, mas tenha acesso aos campos nas tabelas de origem e de destino.
Aqui está o código inteiro que eu usei para testá-lo:
Mais leitura e a fonte de tudo o que sei sobre o assunto está aqui
fonte
Talvez alguém que use o MS SQL Server 2005 ou inferior ache essa resposta útil.
MERGE funcionará apenas para o SQL Server 2008 ou superior. Para descansar, encontrei outra solução alternativa que lhe permitirá criar tipos de tabelas de mapeamento.
Veja como será a resolução do SQL 2005:
O principal truque é que estamos preenchendo a tabela de mapeamento duas vezes com dados ordenados da tabela de origem e destino. Para obter mais detalhes aqui: Mesclando dados inseridos usando OUTPUT no SQL Server 2005
fonte
Output
meusInsert
's para uma saídaTable
que inclui umIdentity
valor a partir do alvoTable
com um não-Insert
valor -ED (PK) a partir da fonteTable
(aliás, de modo que podia, em seguida, (em um lote diferente) que o uso de saídaTable
para preencher umaColumn
em a fonteTable
com oIdentity
valor). Sem aMerge
, imagino que eu teria que: a) começarTransaction
, b) chegar em seguidaIdentity
, c) Inserir em tempTable
com computadoIdentity
, d) definirIdentity_Insert
, e)Insert
no alvo aTable
partir de tempTable
, f) limparIdentity_Insert
.