Inserir com OUTPUT correlacionado à tabela de subconsulta


22

Estou modificando a estrutura de um banco de dados. O conteúdo de várias colunas da tabela FinancialInstitution deve ser transferido para a tabela Person . A FinancialInstitution está vinculada a Person com uma chave estrangeira. Cada Instituição Financeira precisa do ID da sua Pessoa correspondente. Portanto, para cada nova linha inserida em Pessoa, o ID dessa nova linha (IDENTITY) deve ser copiado novamente na linha correspondente de FinancialInstitution.

A maneira óbvia de fazer isso é um código T-SQL iterativo. Mas estou interessado em saber se é possível fazê-lo apenas com operações baseadas em conjuntos.

Imaginei que o nível interno de uma solicitação desse tipo seria algo como:

INSERT INTO Person (Street1, Number1, City1, State1, PostCode1, CountryId1, WorkDirectPhone1, Fax1, Email1)
OUTPUT inserted.Id, FinancialInstitution.Id
SELECT Id, Street, Number, City, [State], PostCode, CountryId, PhoneNumber, Fax, Email
FROM FinancialInstitution;

Infelizmente, parece que OUTPUT não pode se correlacionar dessa maneira ...


Deseja inserir linhas na tabela Person? Ou atualizar os existentes? Ou você deseja inserir Persone depois UPDATE FinancialInstitution?
precisa saber é o seguinte

Sua consulta está atualizando apenas a tabela Pessoa. Você pode capturar o insert.ID, mas não o FinancialInstitution.ID, a menos que você o utilize na parte de inserção. Da maneira como sua consulta fica, se você removesse a cláusula OUTPUT, você receberia um erro porque o número de colunas na sua instrução INSERT não corresponde à instrução SELECT.
datagod

ypercube: desejo inserir na pessoa e atualizar a FinancialInstitution com o ID da nova linha em pessoa.
Yugo Amaryl

datagod: Eu sei que sua única atualização, esta consulta é o nível aninhado da solução futura. Mas eu já estou preso lá. Certo, não consigo adicionar um ID à seleção se não o inserir.
Yugo Amaryl

Respostas:


18

Eu acho que você poderia (ab) usar MERGEpara isso. Primeiro, crie uma tabela (temporária):

CREATE TABLE tempIDs
( PersonId INT, 
  FinancialInstitutionId INT
) ;

Depois, MERGEem Person( em vez de INSERT), para que você possa usar as colunas das tabelas envolvidas na OUTPUTcláusula:

MERGE INTO Person 
USING FinancialInstitution AS fi
  ON 1 = 0
WHEN NOT MATCHED THEN
  INSERT (Street1, Number1, City1, ...)
  VALUES (fi.Street, fi.Number, fi.City, ...)
OUTPUT inserted.Id, fi.Id
  INTO tempIDs ;

Em seguida, use a tabela temporária para UPDATE FinancialInstitution:

UPDATE fi
SET fi.PersonId = t.PersonId
FROM FinancialInstitution AS fi
  JOIN tempIDs AS t
    ON fi.Id = t.FinancialInstitutionId ; 

Teste em: SQL-Fiddle

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.