サブクエリテーブルに関連付けられたOUTPUTで挿入


22

データベースの構造を変更しています。テーブルFinancialInstitutionのいくつかの列の内容は、テーブルPersonに転送する必要があります。FinancialInstitutionは、外部キーを持つPersonにリンクされています。各金融機関には、対応する個人のIDが必要です。そのため、Personに挿入された新しい行ごとに、この新しい行のID(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;

残念ながら、OUTPUTはそのように相関できないようです...


テーブルに行を挿入しますPersonか?または、既存のものを更新しますか?それともに挿入するかPerson、その後とUPDATE FinancialInstitution
ypercubeᵀᴹ

クエリはPersonテーブルのみを更新しています。insert.IDをキャプチャできますが、挿入部分で使用しない限り、FinancialInstitution.IDはキャプチャできません。クエリの配置方法で、OUTPUT句を削除した場合、INSERTステートメントの列数がSELECTステートメントと一致しないため、エラーが発生します。
datagod 14

ypercube:Personに挿入し、Personの新しい行のIDでFinancialInstitutionを更新します。
ユーゴアマリール14

datagod:その唯一の更新を知っています。このクエリは、将来のソリューションのネストレベルです。しかし、私はすでにそこに立ち往生しています。挿入しないと、IDを選択に追加できません。
ユーゴアマリール14

1
@YugoAmaryl、あなたはこの例を採用しようとすることができる複数行挿入のID値をキャプチャするためにOUTPUT句の使用
DenisT

回答:


18

これを(ab)使用できると思いますMERGE。最初に(一時的な)テーブルを作成します。

CREATE TABLE tempIDs
( PersonId INT, 
  FinancialInstitutionId INT
) ;

その後MERGEPerson(代わりに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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.