2016-08-31 3 views
0

ein Von der Benutzeroberfläche übergebe ich eine Datentabelle an eine gespeicherte Prozedur. Der Typ dieses Parameter ist ein frei wählbares Tabellenfeld mit der folgenden StrukturVerwenden Sie MERGE, um Daten zu löschen, oder geben Sie

Personkey int 
ComponentKey varchar 

Diese Daten in eine Tabelle gehen muss, und Daten, die in der Tabelle vorhanden ist, aber nicht in der Datentabelle soll gestrichen werden.

Beispiel Tabellendaten

PersonKey  ComponentKey 
123   A1 
456   B9 

Und meine Datentabelle hat 2 Zeilen, eine passende Zeile und eine neue Zeile

Beispiel Datentabelle Daten

PersonKey ComponentKey 
123   A1 
786   Z6 

Das Ergebnis ist, dass die 456/B9 Zeile sollte gelöscht werden, nichts sollte mit der Zeile 123/A1 passieren, und die Zeile 786/Z6 sollte eingefügt werden.

Ich glaube, ich kann die MERGE-Anweisung verwenden, aber ich bin mir nicht sicher, wie man es formt.

Ich verstehe, dass, wenn nicht abgestimmt, ich den Einsatz tun sollte, aber wo kommt der Löschteil hinein?

MERGE Components 
USING @passedInData 
ON PersonKey = DatatblPersonKey AND ComponentKey = DatatblComponentKey 

WHEN MATCHED THEN 
-- DO nothing... 

WHEN NOT MATCHED 
INSERT (PersonKey, ComponentKey) VALUES (DatatblPersonKey, DatatblComponentey); 

Edit: Nur klar zu sein, könnte die Datentabelle viele Zeilen für die gleiche Person Schlüssel enthalten, aber die Komponente Schlüssel anders sein würde.

Beispiel Datentabelle Daten

PersonKey ComponentKey 
123   Z6 
123   C5 

Beispiel Tabellendaten

PersonKey  ComponentKey 
123   A1 
456   B9 

Das Ergebnis nach der obigen Datentabelle einfügen sollte

sein
PersonKey ComponentKey 
123   Z6 
123   C5 
456   B9 

Beachten Sie, dass 123/A1 gelöscht und 456 wurde/B9 ist immer noch in der Tabelle.

Antwort

0

Der Standard "WENN NICHT ABGESTIMMT" geht davon aus, dass das, was du wirklich meinst, "WENN NICHT MIT ZIEL ABGESTIMMT" ist. Mit dem einfachen Befehl "DELETE" können Sie eine andere Anweisung für "WHEN NOT MATCHED BY SOURCE" ausführen.

Seien Sie vorsichtig, wenn Sie dies tun, da alle Datensätze vom Ziel gelöscht werden, die nicht mit der Quelle übereinstimmen, basierend auf dem von Ihnen angegebenen Vergleich. Wenn es notwendig ist, eine Teilmenge des Ziels für diese Aktion auszuführen, können Sie eine Cte ​​mit diesem Filter verwenden und dann die Zusammenführung mit dieser Cte als Ziel durchführen.

bearbeiten ... zeigen, wie bis haken, was ich sage:

DECLARE @databaseTable TABLE (PersonKey INT, ComponentKey VARCHAR(10)); 
INSERT INTO @databaseTable 
VALUES 
    (123, 'A1'), 
    (456, 'B9'); 
DECLARE @appDataset TABLE (PersonKey INT, ComponentKey VARCHAR(10)); 
INSERT INTO @appDataset 
VALUES 
    (123, 'Z6'), 
    (123, 'C5'); 

WITH cteTarget AS 
    (
    SELECT dt.PersonKey 
     , dt.ComponentKey 
    FROM @databaseTable AS dt 
    JOIN (SELECT DISTINCT PersonKey FROM @appDataset) AS pk 
     ON pk.PersonKey = dt.PersonKey 
    ) 
MERGE cteTarget AS tgt 
USING @appDataset AS src 
    ON src.PersonKey = tgt.PersonKey 
    AND src.ComponentKey = tgt.ComponentKey 
WHEN NOT MATCHED BY SOURCE THEN 
    DELETE 
WHEN NOT MATCHED BY TARGET THEN 
    INSERT 
     (PersonKey 
     ,ComponentKey) 
    VALUES 
     (src.PersonKey 
     ,src.ComponentKey); 

SELECT * FROM @databaseTable; 
+0

ich meine Frage aktualisiert, da dieser Ansatz nicht funktioniert. – andrewb

+1

Ihre Ausführung hat vielleicht nicht funktioniert, aber der Ansatz funktioniert. Ich habe meine Antwort bearbeitet, um die Konstrukte der Daten und die kodierte Lösung für Ihr Problem einzubeziehen. Achten Sie darauf, dass Sie darauf achten müssen, was genau Ihr Ziel ist. – btberry

Verwandte Themen