prog:sql_merge_upsert_same_table_syntax
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
prog:sql_merge_upsert_same_table_syntax [2016/08/17 13:13] – [Normale Lösung mit Update] gpipperr | prog:sql_merge_upsert_same_table_syntax [2016/08/18 20:58] (aktuell) – gpipperr | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | =====Upsert - Mit dem Oracle Merge auf der gleichen Tabelle in einem Befehl ein Update/ | ||
+ | |||
+ | ==== Normale Lösung mit Update ==== | ||
+ | |||
+ | Erst suchen, ob es den Wert schon gibt (count(*)) und dann falls ja => ein " | ||
+ | |||
+ | Oder viel einfacher das " | ||
+ | |||
+ | <code sql> | ||
+ | |||
+ | begin | ||
+ | | ||
+ | update admin_props | ||
+ | set property = ' | ||
+ | where property = ' | ||
+ | | ||
+ | if sql%rowcount = 0 then | ||
+ | | ||
+ | | ||
+ | | ||
+ | , 'Type of the interface' | ||
+ | , ' | ||
+ | , ' | ||
+ | ); | ||
+ | else | ||
+ | dbms_output.put_line(' | ||
+ | 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 <fc # | ||
+ | |||
+ | 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 " | ||
+ | |||
+ | 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! | ||
+ | |||
+ | <code sql> | ||
+ | |||
+ | merge into admin_props p | ||
+ | using (select id | ||
+ | | ||
+ | where property = ' | ||
+ | union | ||
+ | select 1 from dual) t | ||
+ | on (p.id = t.id) | ||
+ | when matched | ||
+ | then | ||
+ | update set property = ' | ||
+ | when not matched | ||
+ | then | ||
+ | | ||
+ | | ||
+ | , 'Type of the interface' | ||
+ | , ' | ||
+ | , ' | ||
+ | ); | ||
+ | | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | |||
+ | ===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 ==== | ||
+ | |||
+ | Für zwei unterschiedliche Tabellen siehe [[prog: | ||
+ | |||
+ | |||
+ | Doku: | ||
+ | |||
+ | Update: | ||
+ | * https:// | ||
+ | |||
+ | Merge: | ||
+ | * https:// | ||
prog/sql_merge_upsert_same_table_syntax.txt · Zuletzt geändert: 2016/08/18 20:58 von gpipperr