none
Merge Update Fehler RRS feed

  • Frage

  • Hallo zusammen

    Ich habe wieder einmal was ganz tolles zum erledigen.

    Ausgangslage: Zieltable = A, Target = B
    In der Table A habe ich eine Spalte welche Dateninhalt haben, diese Daten möchte ich in die spalte der Table B updaten.

    Fehlermeldung: 

    Msg 8672, Level 16, State 1, Line 3

    The MERGE statement attempted to UPDATE or DELETE the same row more than once. This happens when a target row matches more than one source row. A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times. Refine the ON clause to ensure a target row matches at most one source row, or use the GROUP BY clause to group the source rows.

    Table A

    ID Date Aktion

    B11 20130101 Neu
    A22 20130203 defekt
    C12 20130103 neu
    B11 20130110 keine Funktion


    Table B

    ID Date Aktion

    B11 20130101 NULL
    A22 20130203 NULL
    C12 20130103 NULL
    B11 20130110 NULL

    Hier die Query:

    Merge dbo.B as T
    Using (Select   ID
            ,Aktion
            From dbo.A
            where Date between '20120101' and '20130331') as S
    On (T.ID = S.ID)
    
    WHEN MATCHED THEN
          UPDATE SET T.Aktion = S.Aktion 
    Output $action, inserted.*;
    

    Die Option Refin ON habe ich auch nicht. Das Problem könnte ich sicher lösen wenn ich dem beibringen könnte. Die Datensätze Zeile für Zeile durcharbeiten könnte. 

    Beste Grüsse im Voraus.

    Mehmet

    Mittwoch, 17. April 2013 13:14

Alle Antworten

  • Hallo Mehmet,

    Zeile für Zeile gibt es in SQL nicht, denn relationale Datenbanken verwenden einen mengen-/setorientierten Ansatz.
    Damit ein MERGE funktioniert, muss eine eindeutige Zuordnung existieren.

    Und Deine mehrfachen B11 lassen sich keiner eindeutigen Id in A zuordnen.
    Hier könnte eine Lösung sein, den aktuellsten Eintrag über das Datum zu ermitteln:

    WITH BByIdDatum
    AS (SELECT 
    		B.*,
    		ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Id, Datum DESC) AS rn
    	FROM B)
    SELECT Id, Datum, Aktion FROM BByIdDatum AS t
    WHERE rn = 1;

    bei mehreren Änderung am gleichem Datum wird das Ergebnis aber wieder zufällig ausfallen.

    Gruß Elmar

    Mittwoch, 17. April 2013 13:38
    Beantworter
  • Hallo Stefan

    Es ist aber durchaus möglich das ein Eintrag aM GLEICHEN Datum mitmdem gleichen ID eingetragen wird. Diese Datwn werden vom einer Applikation zurück gegeben. Wenn ich in der Merge Klausel in der On nicht nur die ID sondern das Datum vergleiche dann muss es doch von der Logik her klappen 

    On (T.ID = S.ID and T.Date = S.Date)

    Weil dann macht es den Datensatz eindeutig . Am gleichen Datum kommt es nicht vor das eine ID zweimal eingetragen wird.

    Was denkst du darüber? 

    Werde mal kurz versuchen .

    Mittwoch, 17. April 2013 21:18
  • Hallo Mehmet,

    wenn Einträge je ID + Datum existieren sollen, so kannst Du das über die erweiterte Match-Bedingung lösen.

    Dann sollte aber auch der Primärschlüssel aus ID und Datum bestehen.

    Gruß Elmar

    Donnerstag, 18. April 2013 07:03
    Beantworter
  • Hi Elmar

    Kann man das nicht einfach mit einem Update durchfürhen lassen?

    Donnerstag, 18. April 2013 09:05
  • Hallo Mehmet,

    was willst Du mit einem Update durchführen?

    Wenn es um MERGE vs. UPDATE geht:
    MERGE stellt eine zusammengefasste Version für INSERT/UPDATE/DELETE bereit.
    Effektiv wird im UPDATE Fall das gleiche gemacht, was UPDATE auch tut.

    Nur das MATCHED zusätzlich prüft, ob genau eine Zeile je Treffer verändert wird, weil i. a. das Gewollte ist.
    UPDATE tut das nicht, aber das Ergebnis ist in dem Falle unbestimmt / zufällig,
    weil die Änderung davon abhängt, welche Zeile als letzte verarbeitet wird.

    Und bitte nicht dem Irrtum unterliegen, weil SELECT bei der Ausgabe eine Reihenfolge suggeriert,
    dass diese für eine Aktualisierung verwendet wird.  Ohne ein eindeutiges Kriterium
    können mehrere Treffer beliebig verarbeitet werden.

    Auch bei UPDATE sollte die Bedingungen so gewählt werden, das exakt eine Zeile pro Treffer verändert wird.
    Für oben konkret: Du willst die letzte Aktion (für ein Datum) haben und nicht irgendeine beliebige.

    Gruß Elmar

    Donnerstag, 18. April 2013 10:09
    Beantworter