Mithilfe von merge..output zu bekommen mapping zwischen Quelle.id und target.id

Sehr vereinfacht, ich habe zwei Tabellen Quelle und Ziel.

declare @Source table (SourceID int identity(1,2), SourceName varchar(50))
declare @Target table (TargetID int identity(2,2), TargetName varchar(50))

insert into @Source values ('Row 1'), ('Row 2')

Ich würde gerne alle Zeilen aus @Source zu @Target und kennen die TargetID für jeden SourceID da gibt es auch die Tabellen SourceChild und TargetChild dass kopiert werden muss, und ich muss hinzufügen, das neue TargetID in TargetChild.TargetID FK-Spalte.

Gibt es ein paar Lösungen.

  1. Mit einer while-Schleife oder der Cursor um eine Zeile einfügen (RBAR) zum Ziel in einer Zeit und verwenden Sie scope_identity() zu füllen, die FK von TargetChild.
  2. Fügen Sie ein temp-Spalte @Target und einfügen SourceID. Sie kann dann kommen, dass die Spalte zu Holen, die TargetID für die FK in TargetChild.
  3. SET IDENTITY_INSERT OFF für @Target und Griff zuweisen neuer Werte selbst. Sie bekommen ein Angebot, dass Sie dann den Einsatz in TargetChild.TargetID.

Ich bin nicht gern einer von Ihnen. Die, die ich bisher verwendet wird-Cursor.

Was würde ich wirklich tun möchte, ist die Verwendung der output - Klausel der insert-Anweisung.

insert into @Target(TargetName)
output inserted.TargetID, S.SourceID
select SourceName
from @Source as S

Aber es ist nicht möglich

The multi-part identifier "S.SourceID" could not be bound.

Aber es ist möglich, mit einem merge.

merge @Target as T
using @Source as S
on 0=1
when not matched then
  insert (TargetName) values (SourceName)
output inserted.TargetID, S.SourceID;

Ergebnis

TargetID    SourceID
----------- -----------
2           1
4           3

Möchte ich wissen, ob man diese verwendet? Wenn Sie irgendwelche Gedanken über die Lösung oder finden Sie irgendwelche Probleme mit ihm? Es funktioniert gut in einfachen Szenarien, aber vielleicht etwas hässliches passieren könnte, wenn der Abfrage-plan wirklich kompliziert aufgrund einer komplizierten Quell-Abfrage. Schlimmste Szenario wäre, dass TargetID/SourceID Paare eigentlich nicht für ein match.

MSDN hat dies zu sagen über die from_table_name des Ausgabe - Klausel.

Ist ein Spaltenpräfix, das eine Tabelle angibt, enthalten, in der FROM-Klausel einer DELETE -, UPDATE-oder MERGE-Anweisung wird verwendet, um die Zeilen zu aktualisieren oder zu löschen.

Aus irgendeinem Grund Sie nicht sagen, "Zeilen einfügen, aktualisieren oder löschen Sie" nur "den Zeilen zu aktualisieren oder zu löschen".

Irgendwelche Gedanken sind willkommen und völlig unterschiedliche Lösungen für das ursprüngliche problem wird sehr geschätzt.

Der Grund, Sie nicht zu erwähnen 'einfügen' den ist, weil die from_table_name ist ungültig in der insert into - /Ausgabe-Anweisungen, so wird auch die "gelöscht" - Präfix (da keine vorhandenen Daten geändert werden können, über eine insert -)
BTW: Adam Machanic deckt diese Technik hier
Adam Machanic ' s blog post über die Merge-Funktion ist FANTASTISCH! Löste mein problem genauer. Danke Martin Smith für die Buchung. Wünschte, ich könnte mehr geben als nur +1

InformationsquelleAutor Mikael Eriksson | 2011-03-19

Schreibe einen Kommentar