Вставить с 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 в выделение, если я его не вставлю.
— Юго Амарил

Ответы:


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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.