2016-05-18 13 views
1

Ich versuche, Daten von einem System in ein anderes einzufügen, so dass ich eine Zwischenzuordnungstabelle behalten, um die IDs von alten und neuen Tabelle zu behalten. KontoMERGE-Anweisung mit OUTPUT mit WHERE-Bedingung

ich einen MERGE Zustand bin mit, ist es eine Möglichkeit zu

DECLARE @TenantId INT = 1 

MERGE dbo.[Account] AS t 
USING (SELECT m.[AccountId], 
       m.[TenantId], 
       a.[ID_Account], 
       a.[Account_No], 
       a.[Account_Name],    
      FROM [Client1].dbo.[Account] a 
      LEFT JOIN migration.[Account] m ON m.[ID_Account] = a.[ID_Account] AND m.[TenantId] = @TenantId 
    ) AS s 
ON (t.[AccountId] = s.[AccountId] AND t.[TenantId] = s.[TenantId]) 

WHEN NOT MATCHED THEN 
    INSERT ([TenantId], [Number], [Name], [Active]) 
    VALUES (@TenantId, s.[Account_No], s.[Account_Name], 1) 
    OUTPUT @TenantId, inserted.[AccountId], s.[ID_Account] INTO migration.[Account]; 

Das ist in Ordnung, aber wenn ich versuche, es ein zweites Mal ausführen, werden die Datensätze eingefügt wieder auf meiner Migration. [ ] Tabelle, die wiederholte Daten enthält. Gibt es eine Möglichkeit, eine Bedingung auf die Ausgabe zu setzen?

+3

Können Sie einige Beispieldaten zeigen, a * komplette * 'MERGE' Aussage, und erklären, wie man die Dinge erwarten, wenn die Arbeit Sie führen diese Zusammenführung zweimal aus? –

+1

Wenn du Duplikate erhältst, klingt es so, als ob die Bedingung (en) von 'MERGE' die Datensätze nicht korrekt identifizieren, wenn sie übereinstimmen und wenn sie nicht übereinstimmen. Ohne etwas anderes spezifiziert zu sein, ist das "NOT MATCHED" dasselbe wie das "NOT MATCHED BY TARGET". – Steven

+0

Bin ich richtig, dass die "echte" Zieltabelle gut funktioniert und nur die "historische" Tabelle - um Ihre Änderungen zu verfolgen - Duplikate hat? In diesem Fall könnte es eine Möglichkeit geben, einen Trigger auf diese Tabelle zu setzen ... – Tyron78

Antwort

0

Wenn Sie überprüfen, um zu sehen, ob Werte aus der Quelle im Ziel vorhanden sind, können Sie überprüfen, um zu sehen, ob die AccountId von migration.Account ist gleich der AccountId von dbo.Account. Sie geben die Ergebnisse in der Migrationstabelle aus, aber der ursprüngliche Datensatz ist weiterhin vorhanden, sodass er in nachfolgenden Ausführungen der Zusammenführung enthalten ist.

Um Ihr Problem zu beheben müssen Sie entweder:

  • den ursprünglichen Datensatz Tabelle
  • hinzufügen isUpdated Spalt in der Migration löschen, die Sie nach dem Einfügen aktualisieren und die Quelle dessen Laden verhindern.
  • Aktualisieren Sie die AccountId mit der neuen AccountId, damit die Bedingung bei nachfolgenden Ausführungen erfüllt wird.
  • Haben Sie den neuen Datensatz irgendwie das Original im Quelldatensatz abbrechen.

Hier ist ein Verfahren mit einem neuen isUpdated und aktualisiert die accountId Säule:

UPDATE m SET 
    isUpdated = 1, 
    AccountId = o.NewAccountId 
FROM migration.Account [m] 
INNER JOIN (
    MERGE dbo.[Account] AS t 
    USING (SELECT m.[AccountId], 
        m.[TenantId], 
        a.[ID_Account], 
        a.[Account_No], 
        a.[Account_Name],    
       FROM [Client1].dbo.[Account] a 
       LEFT JOIN migration.[Account] m ON m.[ID_Account] = a.[ID_Account] 
        AND m.[TenantId] = @TenantId 
       WHERE m.isUpdated IS NULL OR m.isUpdated = 0 
     ) AS s 
    ON (t.[AccountId] = s.[AccountId] AND t.[TenantId] = s.[TenantId]) 

    WHEN NOT MATCHED THEN 
     INSERT ([TenantId], [Number], [Name], [Active]) 
     VALUES (@TenantId, s.[Account_No], s.[Account_Name], 1) 
     OUTPUT @TenantId, s.AccountId [OriginalAccountId], inserted.[NewAccountId] 
) [o] ON o.TenantId = m.TenantId AND o.OriginalAccountId = m.AccountId 
0

Was möchten Sie tun ist Updates zu tun, wenn angepasst:

MERGE into dbo.[Account] AS destination 
USING (SELECT m.[AccountId], 
       m.[TenantId], 
       a.[ID_Account], 
       a.[Account_No], 
       a.[Account_Name],    
      FROM [Client1].dbo.[Account] a 
      LEFT JOIN migration.[Account] m ON m.[ID_Account] = a.[ID_Account] AND m.[TenantId] = @TenantId 
    ) AS holdinarea 
ON (destination.[AccountId] = holdinarea.[AccountId] AND destination.[TenantId] = holdinarea.[TenantId]) 
WHEN MATCHED THEN 
    UPDATE set [AccountId]=holdinarea.accountid, 
       [TenantId]=holdinarea.tenantID 
WHEN NOT MATCHED THEN 
    INSERT ([TenantId], [Number], [Name], [Active]) 
    VALUES (holdingarea.TenantId, holdingarea.[Account_No], holdingarea.[Account_Name], 1); 
+0

Ich möchte die IDs von alter Tabelle in neue Tabelle in meine Tabellenmigration einfügen [Account]. Da es sich um eine Zusammenführung handelt, wenn ich es ein zweites Mal ausführe, werden Datensätze erneut in die Zuordnungstabelle eingefügt, aber ich brauche sie nicht wirklich, weil sie vorher eingefügt wurde. Ich kann eine temporäre Tabelle erstellen und sie dann einfügen, wenn sie nicht existiert, aber ich frage mich, ob ich es direkt tun kann – carlosm

+0

OK, so sollte die Zusammenführung aktualisieren, wenn sie übereinstimmen und einfügen, wenn nicht. Wie Sie sehen können, habe ich die erste Anweisung (MERGE in dbo. [Account] AS-Destination) als Ziel und die using-Abfrage als Haltebereich markiert. Wenn Sie die Zusammenführungs-Anweisung auf diese Weise verwenden, wird sie nicht erneut eingefügt, wenn sie übereinstimmt. Wie Sie sehen können, finden sowohl das Update als auch das Einfügen in der Zieltabelle statt (in diesem Fall dbo.account). Datensätze sollten nicht in die Zuordnungstabelle eingefügt werden, wenn Sie nur am Ziel einfügen –