Einfügen mit AUSGABE korreliert mit Unterabfragetabelle

22

Ich ändere die Struktur einer Datenbank. Der Inhalt mehrerer Spalten der Tabelle FinancialInstitution muss in die Tabelle Person übertragen werden . FinancialInstitution ist mit einer Person mit einem Fremdschlüssel verknüpft. Jede FinancialInstitution benötigt die ID ihrer entsprechenden Person. Für jede neue Zeile, die in Person eingefügt wird, muss die ID dieser neuen Zeile (IDENTITY) zurück in die entsprechende Zeile von FinancialInstitution kopiert werden.

Die naheliegende Möglichkeit hierfür ist ein iterativer T-SQL-Code. Ich bin jedoch daran interessiert zu wissen, ob dies nur mit satzbasierten Operationen möglich ist.

Ich stellte mir vor, dass die innere Ebene einer solchen Anfrage ungefähr so ​​aussehen würde:

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;

Leider kann OUTPUT nicht auf diese Weise korrelieren ...

Yugo Amaryl
quelle
Möchten Sie Zeilen in die Tabelle einfügen Person? Oder bestehende aktualisieren? Oder möchtest du in Personund dann einfügen UPDATE FinancialInstitution?
Ypercubeᵀᴹ
Ihre Abfrage aktualisiert nur die Personentabelle. Sie können die eingefügte.ID erfassen, jedoch nicht die FinancialInstitution.ID, es sei denn, Sie verwenden sie im Einfügeteil. Wenn Sie die OUTPUT-Klausel auf die Art und Weise Ihrer Abfrage entfernen, erhalten Sie eine Fehlermeldung, da die Anzahl der Spalten in Ihrer INSERT-Anweisung nicht mit der SELECT-Anweisung übereinstimmt.
Datum
ypercube: Ich möchte in Person einfügen und dann FinancialInstitution mit der ID der neuen Zeile in Person aktualisieren.
Yugo Amaryl
datagod: Ich weiß, dass es nur aktualisiert wird. Diese Abfrage ist die verschachtelte Ebene der zukünftigen Lösung. Aber ich stecke schon fest. Richtig, ich kann der Auswahl keine ID hinzufügen, wenn ich sie nicht einfüge.
Yugo Amaryl
1
@YugoAmaryl, Sie können versuchen, dieses Beispiel zu übernehmen. Verwenden der OUTPUT-Klausel zum Erfassen von Identitätswerten auf
mehrzeiligen Einfügungen

Antworten:

18

Ich denke, Sie könnten (ab) dafür verwenden MERGE. Erstellen Sie zuerst eine (temporäre) Tabelle:

CREATE TABLE tempIDs
( PersonId INT, 
  FinancialInstitutionId INT
) ;

Dann MERGEin Person(anstelle von INSERT), damit Sie Spalten der in die OUTPUTKlausel einbezogenen Tabellen verwenden können :

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 ;

Verwenden Sie dann die temporäre Tabelle, um UPDATE FinancialInstitution:

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

Test bei: SQL-Fiddle

ypercubeᵀᴹ
quelle