INSERT SELECT: Mapping zwischen alten und neuen IDs
-
Hi,
Beispiel: ich hab eine Tabelle "tabelle" mit den Spalten "ID" (int) und "Value" (nvarchar(max)). ID hat auto increment aktiviert. Und eine zweite Tabelle "wo_anders" mit den gleichen Spalten.
Wenn ich jetzt sowas mache:
INSERT INTO tabelle ( id , value ) SELECT id , value FROM wo_anders
und ich brauche das Mapping zwischen der alten ID (die aus wo_anders) und der neuen (die gerade in "tabelle" eingefügt wurde). Wie krieg ich das gebacken? Mein Ansatz:
DECLARE @copyValues TABLE ( id INT , value NVARCHAR(MAX) , rownum INT ); INSERT INTO @copyValues ( id , value , rownum ) SELECT id , value , ROW_NUMBER() OVER(ORDER BY ID) FROM wo_anders ORDER BY id DECLARE @newIDs TABLE ( id INT ) INSERT INTO tabelle ( value ) OUTPUT INSERTED.id INTO @newIDs SELECT value FROM @copyValues ORDER BY id DECLARE @mapping TABLE ( id INT , rownum INT ) INSERT INTO @mapping ( id , rownum ) SELECT id , ROW_NUMBER() OVER(ORDER BY id) FROM @newIDs SELECT c.id AS oldID , m.id AS newID FROM @copyValues c INNER JOIN @mapping m ON c.rownum = m.rownum
Das funktioniert auch, aber es is relativ viel Code für relativ wenig Ergebnis. Geht das nicht einfacher? Wichtig ist dabei, dass es ein INSERT SELECT ist, weil es viele Datensätze sein können und drüber loopen zu lang dauern würde.
-
Mit Identity spart man sich sogar noch ein paar Zeilen:
DECLARE @copyValues TABLE ( id INT , value NVARCHAR(MAX) , rownum INT ); INSERT INTO @copyValues ( id , value , rownum ) SELECT id , value , ROW_NUMBER() OVER(ORDER BY ID) FROM wo_anders ORDER BY id DECLARE @newIDs TABLE ( id INT , rownum INT IDENTITY(1, 1) ) INSERT INTO tabelle ( value ) OUTPUT INSERTED.id INTO @newIDs SELECT value FROM @copyValues ORDER BY id SELECT c.id AS oldID , n.id AS newID FROM @copyValues c INNER JOIN @newIDs n ON c.rownum = n.rownum
-
Hat denn wirklich keiner eine Idee?