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 ...

Yugo Amaryl
fonte
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
1
@YugoAmaryl, você pode tentar adoptar este exemplo usando a cláusula OUTPUT para capturar valores de identidade em várias linhas Inserções
denist

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

ypercubeᵀᴹ
fonte