Insérer avec OUTPUT corrélé à la sous-table de requête


22

Je modifie la structure d'une base de données. Le contenu de plusieurs colonnes du tableau FinancialInstitution doit être transféré dans le tableau Personne . FinancialInstitution est lié à la personne avec une clé étrangère. Chaque institution financière a besoin de l'ID de sa personne correspondante. Ainsi, pour chaque nouvelle ligne insérée dans Person, l'ID de cette nouvelle ligne (IDENTITY) doit être recopié dans la ligne correspondante de FinancialInstitution.

La façon évidente de le faire est un code T-SQL itératif. Mais je suis intéressé de savoir s'il est possible de le faire uniquement avec des opérations basées sur des ensembles.

J'ai imaginé que le niveau interne d'une telle demande serait quelque chose comme:

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;

Malheureusement, il semble que OUTPUT ne puisse pas être corrélé de cette façon ...


Voulez-vous insérer des lignes dans le tableau Person? Ou mettre à jour ceux existants? Ou voulez-vous insérer dans Personet ensuite UPDATE FinancialInstitution?
ypercubeᵀᴹ

Votre requête met uniquement à jour la table Person. Vous pouvez capturer l'ID inséré, mais pas l'ID FinancialInstitution sauf si vous l'utilisez dans la partie d'insertion. La façon dont votre requête se situe, si vous supprimez la clause OUTPUT, vous obtiendrez une erreur car le nombre de colonnes dans votre instruction INSERT ne correspond pas à l'instruction SELECT.
datagod

ypercube: Je souhaite insérer dans Person, puis mettre à jour FinancialInstitution avec l'ID de la nouvelle ligne dans Person.
Yugo Amaryl

datagod: Je connais sa seule mise à jour, cette requête est le niveau imbriqué de la future solution. Mais je suis déjà coincé là-bas. À droite, je ne peux pas ajouter Id dans la sélection si je ne l'insère pas.
Yugo Amaryl

Réponses:


18

Je suppose que vous pourriez (ab) utiliser MERGEpour cela. Créez d'abord une table (temporaire):

CREATE TABLE tempIDs
( PersonId INT, 
  FinancialInstitutionId INT
) ;

Puis MERGEdans Person(au lieu de INSERT), vous pouvez donc utiliser les colonnes des tables impliquées dans la OUTPUTclause:

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 ;

Utilisez ensuite la table temporaire pour UPDATE FinancialInstitution:

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

Testez à: SQL-Fiddle

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.