SQL Insert, Update und Delete in einem: Das MERGE-Kommando
Erscheinungsmonat |
APEX-Version |
Datenbankversion |
November 2011 |
alle |
9.2 |
Wie alle anderen Entwickler kommt auch der APEX-Entwickler immer wieder in die
Verlegenheit, eine oder mehrere Zeilen in eine Tabelle "hineinzumischen". Wenn die
Zeile also schon da ist, soll ein SQL UPDATE stattfinden, wenn sie noch nicht da ist,
wird ein INSERT gemacht.
Vielfach hilft man sich dann mit PL/SQL-Prozeduren, die zuerst mal einen INSERT versuchen,
und wenn ein Fehler auftritt (DUP_VAL_ON_INDEX) ein UPDATE machen.
Das geht aber auch eleganter: mit dem MERGE-Kommando. Dieses gibt es bereits seit Oracle9i -
und in Oracle10g wurde es nochmals erweitert. Es wurde zwar vor allem für Ladeprozesse in
Datawarehouse-Umgebungen entwickelt, dadurch ist es für APEX aber nicht weniger nützlich. So ist
MERGE bspw. hervorragend geeignet, um die Inhalte einer APEX-Collection in eine Tabelle zu
übertragen. In
diesem Tipp wird das MERGE-Kommando und seine Anwendung vorgestellt.
Als Beispiel dient die bekannte Tabelle EMP. In einer zusätzlichen Tabelle
EMP_NEW sind bereits einige Zeilen enthalten; und die Inhalte aus der Tabelle EMP
sollen dort hineingemischt werden.
Das Kommando ist eigentlich selbsterklärend: Man kann sehr schön die einzelnen
Abschnitte erkennen:
- MERGE INTO ... gibt das Ziel der MERGE-Operation an (typischerweise eine Tabelle)
- USING ... gibt die Datenquelle an; das kann eine Tabelle, eine View oder eine SELECT-Abfrage, welche Literale "from DUAL" selektiert, sein.
- ON (matching-kriterium) legt fest, wie bereits vorhandene Zeilen erkannt werden sollen - hier anhand der EMPNO. Aber auch komplerere Kriterien sind möglich.
- WHEN MATCHED ... legt fest, was passieren soll, wenn die Zeile schon da ist; in diesem Fall soll ein SQL UPDATE erfolgen; die Spalteninhalte der Zieltabelle sollen mit denen der Quelldaten überschrieben werden.
- WHEN NOT MATCHED ... legt fest, was passieren soll, wenn die Zeile nicht vorhanden ist; in diesem Fall findet ein SQL INSERT statt - die Zeile wird anhand der Quelldaten erzeugt.
MERGE kann jedoch ab Oracle10g noch mehr ... So sollen die Zeilen der DEPTNO 30
nicht mehr in die Zieltabelle gemischt werden. Das sieht dann wie folgt aus:
Mit Hilfe von SQL MERGE kann man quasi eine WHERE-Klausel an eine Einfügeoperation
hängen. Alle Zeilen mit DEPTNO = 30 werden also nicht aus EMP an EMP_NEW übertragen.
Aber die Zeilen, die bereits vor der MERGE-Operation existierten, sind immer noch da. Der
nächste Schritt wäre nun, die Zeile in der Zieltabelle zu löschenx, wenn in
der Quelltabelle die DEPTNO auf "30" gesetzt ist.
Und MERGE kann (ab Oracle10g) auch das - mit der DELETE-Klausel:
So kann man in einem Ladeprozeß auch Zeilen mit einem "Löschflag" versehen und
mit MERGE dann gezielt löschen. Wie man sieht, ist MERGE ein sehr mächtiges Kommando -
viele Ladevorgänge, aber auch Einzelsatzoperationen, lassen sich so mit einem
einzigen SQL-Kommando erledigen - und das ist effizienter und leichter wartbar,
als selbstprogrammierte PL/SQL-Schleifenkonstrukte.
Und Operationen auf größeren Datenbeständen sind mit MERGE nahezu immer schneller als
mit PL/SQL-Konstrukten. Mehr Informationen finden sich in der
Dokumentation.
Zurück zur Community-Seite
|