Вставить с OUTPUT, соотнесенным с таблицей подзапросов

22

Я изменяю структуру базы данных. Содержимое нескольких столбцов таблицы FinancialInstitution должно быть перенесено в таблицу Person . FinancialInstitution связано с лицом с внешним ключом. Каждому финансовому учреждению необходим идентификатор соответствующего лица. Таким образом, для каждой новой строки, вставленной в Person, идентификатор этой новой строки (IDENTITY) должен быть скопирован обратно в соответствующую строку FinancialInstitution.

Очевидный способ сделать это - итеративный код T-SQL. Но мне интересно знать, возможно ли это сделать только с помощью операций на основе множеств.

Я предполагал, что внутренний уровень такого запроса будет примерно таким:

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;

К сожалению, кажется, что ВЫХОД не может соотноситься таким образом ...

Юго Амарил
источник
Вы хотите вставить строки в таблицу Person? Или обновить существующие? Или ты хочешь вставить Personи потом UPDATE FinancialInstitution?
ypercubeᵀᴹ
Ваш запрос только обновляет таблицу Person. Вы можете захватить вставленный ID, но не FinancialInstitution.ID, если не используете его в части вставки. Как устроен ваш запрос, если вы удалите предложение OUTPUT, вы получите ошибку, потому что число столбцов в вашем операторе INSERT не совпадает с оператором SELECT.
датагод
ypercube: я хочу вставить в Person, а затем обновить FinancialInstitution с идентификатором новой строки в Person.
Юго Амарил
DataGod: я знаю, что его единственное обновление, этот запрос является вложенным уровнем будущего решения. Но я уже застрял там. Да, я не могу добавить Id в выделение, если я его не вставлю.
Юго Амарил
1
@YugoAmaryl, вы можете попытаться применить этот пример, используя предложение OUTPUT для захвата значений идентичности на
многорядных вставках

Ответы:

18

Я думаю, вы могли бы (ab) использовать MERGEдля этого. Сначала создайте (временную) таблицу:

CREATE TABLE tempIDs
( PersonId INT, 
  FinancialInstitutionId INT
) ;

Затем MERGEв Person(вместо INSERT), чтобы вы могли использовать столбцы таблиц, участвующих в OUTPUTпредложении:

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 ;

Затем используйте временную таблицу для UPDATE FinancialInstitution:

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

Тест в: SQL-Fiddle

ypercubeᵀᴹ
источник