J'ai apporté quelques modifications à ma base de données et je dois migrer les anciennes données vers les nouvelles tables. Pour cela, je dois remplir un tableau (ReportOptions) en prenant les données du tableau d'origine (Practice), et remplir un second tableau intermédiaire (PracticeReportOption).
ReportOption (ReportOptionId int PK, field1, field2...)
Practice (PracticeId int PK, field1, field2...)
PracticeReportOption (PracticeReportOptionId int PK, PracticeId int FK, ReportOptionId int FK, field1, field2...)
J'ai fait une requête pour obtenir toutes les données dont j'ai besoin pour passer de Practice à ReportOptions, mais j'ai du mal à remplir le tableau intermédiaire
--Auxiliary tables
DECLARE @ReportOption TABLE (PracticeId int /*This field is not on the actual ReportOption table*/, field1, field2...)
DECLARE @PracticeReportOption TABLE (PracticeId int, ReportOptionId int, field1, field2)
--First I get all the data I need to move
INSERT INTO @ReportOption
SELECT P.practiceId, field1, field2...
FROM Practice P
--I insert it into the new table, but somehow I need to have the repation PracticeId / ReportOptionId
INSERT INTO ReportOption (field1, field2...)
OUTPUT @ReportOption.PracticeId, --> this is the field I don't know how to get
inserted.ReportOptionId
INTO @PracticeReportOption (PracticeId, ReportOptionId)
SELECT field1, field2
FROM @ReportOption
--This would insert the relationship, If I knew how to get it!
INSERT INTO @PracticeReportOption (PracticeId, ReportOptionId)
SELECT PracticeId, ReportOptionId
FROM @ReportOption
Si je pouvais référencer un champ qui n'est pas sur la table de destination sur la clause OUTPUT, ce serait génial (je pense que je ne peux pas, mais je ne sais pas avec certitude). Des idées pour répondre à mon besoin?
sql
sql-server
Alejandro B.
la source
la source
OUTPUT
clause. Ainsi, même si vous ne fournissez pas de valeur pour une colonne donnée dans votreINSERT
instruction, vous pouvez toujours spécifier cette colonne dans laOUTPUT
clause. Vous ne pouvez cependant pas renvoyer de variables SQL ou de colonnes d'autres tables.Réponses:
Vous pouvez le faire en utilisant
MERGE
au lieu d'insérer:alors remplacez ça
avec
La clé est d'utiliser un prédicat qui ne sera jamais vrai (1 = 0) dans la condition de recherche de fusion, donc vous effectuerez toujours l'insertion, mais aurez accès aux champs des tables source et de destination.
Voici le code complet que j'ai utilisé pour le tester:
Plus de lecture, et la source de tout ce que je sais sur le sujet est ici
la source
Peut-être que quelqu'un qui utilise MS SQL Server 2005 ou une version antérieure trouvera cette réponse utile.
MERGE fonctionnera uniquement pour SQL Server 2008 ou version ultérieure. Pour le reste, j'ai trouvé une autre solution de contournement qui vous donnera la possibilité de créer des types de tables de mappage.
Voici à quoi ressemblera la résolution pour SQL 2005:
L'astuce principale est que nous remplissons la table de mappage deux fois avec des données ordonnées de la table source et de destination. Pour plus de détails ici: Fusion de données insérées à l'aide de OUTPUT dans SQL Server 2005
la source
Output
monInsert
's vers une sortieTable
qui inclut uneIdentity
valeur de la cibleTable
avec uneInsert
valeur non -ed (le PK) de la sourceTable
(btw, donc je pourrais alors (dans un autre lot) utiliser cette sortieTable
pour remplir unColumn
in la sourceTable
avec laIdentity
valeur). Sans aMerge
, j'imagine que je devrais: a) démarrerTransaction
, b) passer au suivantIdentity
, c) insérer dans tempTable
avec calculéIdentity
, d) définirIdentity_Insert
, e)Insert
dans la cibleTable
de tempTable
, f) effacerIdentity_Insert
.