2012-06-08 2 views
73

Ich habe einige Änderungen an meiner Datenbank vorgenommen, und ich muss die alten Daten zu den neuen Tabellen migrieren. Dafür muss ich eine Tabelle (ReportOptions) ausfüllen, die Daten aus der Originaltabelle (Practice) übernimmt, und eine zweite Zwischentabelle (PracticeReportOption) ausfüllen.Ist es möglich, für SQL Output-Klausel eine Spalte zurückgegeben werden, nicht eingefügt?

ReportOption (ReportOptionId int PK, field1, field2...) 
Practice (PracticeId int PK, field1, field2...) 
PracticeReportOption (PracticeReportOptionId int PK, PracticeId int FK, ReportOptionId int FK, field1, field2...) 

habe ich eine Abfrage alle Daten bekommen muss ich aus der Praxis zu Report bewegen, aber ich habe Probleme bei der Zwischentisch

--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 

zu füllen Wenn ich ein Feld verweisen könnte, die ist nicht auf der Zieltabelle in der OUTPUT-Klausel, das wäre großartig (ich denke, ich kann nicht, aber ich weiß es nicht genau). Irgendwelche Ideen, wie ich mein Bedürfnis befriedigen kann?

Vielen Dank im Voraus.

+0

Sie können jede der Spalten der Tabelle, in die Sie eine Zeile einfügen, in Ihre OUTPUT-Klausel zurückgeben. Auch wenn Sie in Ihrer INSERT-Anweisung keinen Wert für eine bestimmte Spalte angeben, können Sie diese Spalte dennoch in der OUTPUT-Klausel angeben. Sie können jedoch keine SQL-Variablen oder Spalten aus anderen Tabellen zurückgeben. –

+0

@marc_s danke für Ihre Antwort, aber ich habe nicht das Feld, das ich brauche in der Zieltabelle (Ich brauche PracticeId, die nicht auf ReportOption ist) –

Antwort

117

Sie können dies tun, indem MERGE anstelle des Einsatzes mit:

so ersetzen diese

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 

mit

MERGE INTO ReportOption USING @ReportOption AS temp ON 1 = 0 
WHEN NOT MATCHED THEN 
    INSERT (field1, field2) 
    VALUES (temp.Field1, temp.Field2) 
    OUTPUT temp.PracticeId, inserted.ReportOptionId, inserted.Field1, inserted.Field2 
    INTO @PracticeReportOption (PracticeId, ReportOptionId, Field1, Field2); 

Der Schlüssel zu einer Aussage verwenden, die niemals wahr sein (1 = 0) in der Zusammenführungs-Anweisung, so dass Sie immer die Einfügung ausführen, aber Zugriff auf Felder in den Quell- und Zieltabellen haben.


Hier ist der gesamte Code, den ich verwendet, um es zu testen:

CREATE TABLE ReportOption (ReportOptionID INT IDENTITY(1, 1), Field1 INT, Field2 INT) 
CREATE TABLE Practice (PracticeID INT IDENTITY(1, 1), Field1 INT, Field2 INT) 
CREATE TABLE PracticeReportOption (PracticeReportOptionID INT IDENTITY(1, 1), PracticeID INT, ReportOptionID INT, Field1 INT, Field2 INT) 

INSERT INTO Practice VALUES (1, 1), (2, 2), (3, 3), (4, 4) 


MERGE INTO ReportOption r USING Practice p ON 1 = 0 
WHEN NOT MATCHED THEN 
    INSERT (field1, field2) 
    VALUES (p.Field1, p.Field2) 
    OUTPUT p.PracticeId, inserted.ReportOptionId, inserted.Field1, inserted.Field2 
    INTO PracticeReportOption (PracticeId, ReportOptionId, Field1, Field2); 

SELECT * 
FROM PracticeReportOption 

DROP TABLE ReportOption 
DROP TABLE Practice 
DROP TABLE PracticeReportOption 

Mehr Lesen, und die Quelle von allem, was ich über das Thema wissen, ist Here

+1

Danke, das macht den Trick! Ich würde ein falsches Temp-Feld verwenden, aber das ist viel eleganter. –

+0

Ausgezeichnet! Dieser Trick ist ein Körnchen Gold! Zur ersten Zeile in der Sammlung hinzugefügt! –

+0

Dies ist genau das, was ich gesucht habe, danke! – fhilton

11

Vielleicht hat jemand Wer verwendet MS SQL Server 2005 oder niedriger wird diese Antwort nützlich finden.


MERGE funktioniert nur für SQL Server 2008 oder höher. Für den Rest habe ich eine andere Problemumgehung gefunden, die Ihnen die Möglichkeit geben wird, eine Art von Mappingtabellen zu erstellen.

Hier ist, wie Auflösung für SQL 2005 aussehen wird:

DECLARE @ReportOption TABLE (ReportOptionID INT IDENTITY(1, 1), Field1 INT, Field2 INT) 
DECLARE @Practice TABLE(PracticeID INT IDENTITY(1, 1), Field1 INT, Field2 INT) 
DECLARE @PracticeReportOption TABLE(PracticeReportOptionID INT IDENTITY(1, 1), PracticeID INT, ReportOptionID INT, Field1 INT, Field2 INT) 

INSERT INTO @Practice (Field1, Field2) VALUES (1, 1) 
INSERT INTO @Practice (Field1, Field2) VALUES (2, 2) 
INSERT INTO @Practice (Field1, Field2) VALUES (3, 3) 
INSERT INTO @Practice (Field1, Field2) VALUES (4, 4) 

INSERT INTO @ReportOption (field1, field2) 
    OUTPUT INSERTED.ReportOptionID, INSERTED.Field1, INSERTED.Field2 INTO @PracticeReportOption (ReportOptionID, Field1, Field2) 
    SELECT Field1, Field2 FROM @Practice ORDER BY PracticeID ASC; 


WITH CTE AS (SELECT PracticeID, ROW_NUMBER() OVER (ORDER BY PracticeID ASC) AS ROW FROM @Practice) 
UPDATE M SET M.PracticeID = S.PracticeID 
    FROM @PracticeReportOption AS M 
    JOIN CTE AS S ON S.ROW = M.PracticeReportOptionID 

    SELECT * FROM @PracticeReportOption 

Haupt Trick ist, dass wir Zuordnungstabelle zweimal mit geordneten Daten aus Quell- und Zieltabelle füllen. Für weitere Details hier: Merging Inserted Data Using OUTPUT in SQL Server 2005

Verwandte Themen