Benutzer-Werkzeuge

Webseiten-Werkzeuge


Action disabled: index
prog:sql_merge_upsert_same_table_syntax

Upsert - Mit dem Oracle Merge auf der gleichen Tabelle in einem Befehl ein Update/Insert nach Bedarf durchführen

Normale Lösung mit Update

Erst suchen, ob es den Wert schon gibt (count(*)) und dann falls ja ⇒ ein „update“, falls kein Datensatz gefunden ⇒ ein „insert“ durchführen.

Oder viel einfacher das „update“ versuchen und auf SQL%ROWCOUNT abfragen.

BEGIN
 
  UPDATE admin_props
     SET property = 'DIF' 
   WHERE property = 'EXPORT_TYPE';
 
   IF sql%rowcount = 0 THEN
     dbms_output.put_line('-- Insert the value');
     INSERT INTO admin_props (id, description, property, VALUE)
     VALUES (1
	  , 'Type of the interface'
	  , 'EXPORT_TYPE'
	  , 'DIF'
      );
   ELSE
      dbms_output.put_line('-- values was updated');
   END IF;
 
END;

Damit benötigen wir aber immer auch etwas PL/SQL um das umzusetzen.


Lösung mit dem Merge Commando

Das Merge Kommando prüft mit der ON Klausel auf Gleichheit, nur wenn WERT1=WERT2 = TRUE wird der Match Block durchgeführt.

Wir wollen nun, falls der Wert noch nicht in der Tabelle existiert, den Wert neu hinzufügen.

Falls er aber schon existiert soll der Wert nur aktualisiert werden.

Im ersten Schritt prüfen wir also in der USING Klausel mit einem Select auf die gleiche Tabelle, ob es den Wert schon gibt.

Das funktioniert aber nicht!

Ist der Datensatz nicht in der Tabelle enthalten gibt eine einfache Abfrage kein Ergebnis zum Vergleichen aus!

Und damit vergleichen wir NICHTS mit etwas in der ON Klausel ⇒ das klappt nicht!

Daher müssen wir mit der Union Anweisung in der SQL Abfrage ein Ergebnis aus dieser Abfrage erzwingen, so das wenigstens eine Zeile zum Vergleich zurück gegeben wird.

Dies Zeile muss dann den gewünschten ID Value enthalten!

Sonst funktioniert der nächste Update nicht, da ja wieder neu eingefügt wird für die „erzeugte“ ID aus der Dual Abfrage!

Soll ein Merge auf die gleiche Tabelle durchgeführt werden, muss das using select also immer min eine Zeile mit der richtigen ID für das Insert zurückgeben!

 MERGE INTO admin_props p
 USING (SELECT id
 	  FROM admin_gcm_props
	 WHERE property = 'EXPORT_TYPE'
  	 UNION
  	 SELECT 1 FROM dual) t
   ON (p.id = t.id)
 WHEN matched
 THEN
    UPDATE SET property = 'DIF'
 WHEN NOT matched
 THEN
   INSERT (id, description, property, VALUE)
   VALUES (   t.id
	 , 'Type of the interface'
	 , 'EXPORT_TYPE'
	 , 'DIF'
  );
 

Mögliche Fehler

ORA-30926: unable to get a stable set of rows in the source tables

Darauf achten das die using Klausel select Abfrage keine doppelten Werte liefert!


Quellen

Diese Website verwendet Cookies. Durch die Nutzung der Website stimmen Sie dem Speichern von Cookies auf Ihrem Computer zu. Außerdem bestätigen Sie, dass Sie unsere Datenschutzbestimmungen gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website.Weitere Information
prog/sql_merge_upsert_same_table_syntax.txt · Zuletzt geändert: 2016/08/18 20:58 von gpipperr