Unsere Datenschutzrichtlinie wird in Kürze aktualisiert. Bitte sehen Sie sich die Vorschau an.

SQL Grundkurs 1: Die Sprache erlernen

MERGE mit Oracle

Testen Sie unsere 2019 Kurse

10 Tage kostenlos!

Jetzt testen Alle Abonnements anzeigen
Die Oracle-Syntax der MERGE-Anweisung weicht von jener des SQL Servers etwas ab und dieses Video zeigt die Unterschiede auf. Achten Sie vor allem darauf, welche Version Sie verwenden, denn den vollen Funktionsumfang gibt es erst ab der Version 10g.

Transkript

In diesem Video sehen Sie, wie Oracle die SQL MERGE-Anweisung implementiert hat. Um Ihnen das zu zeigen, habe ich folgendes Beispiel vorbereitet. Wir kennen ja bereits die Tabelle "artikelgruppen". Diese enthält einerseits in der Spalte "ARTGR" Artikelgruppenkürzel und in der Spalte "GRTEXT" den dazu gehörigen Landtext. Die MERGE-Anweisung wird dazu verwendet, um Änderungen von einem Datenbestand in einen anderen zu übernehmen, D.h. inhaltliche Änderungen zu übertragen, neue Werte, die es in der Zieltabelle noch nicht gibt, einzufügen und Werte, die es zwar in der Ursprungstabelle aber in der Zieltabelle nicht mehr gibt, auch wieder herauszulöschen. Dazu habe ich die Tabelle "gruppen1" vorbereitet. Betrachten wir uns den Inhalt dieser Tabelle. Dieser ist sehr ähnlich, hat aber einen bisschen anderen Aufbau. Genau genommen; der Aufbau ist der selbe, aber die Spaltenbezeichnungen unterscheiden sich. Das Kürzel trägt hier den Namen "ID" und anstelle von "GRTEXT" verwende ich hier "BEZEICHNUNG". Der inhaltliche Unterschied ist der, dass zwei zusätzliche Artikelgruppen hier auftauchen, nämlich die "Blu-ray Discs", sowie die "Bücher". Außerdem hat sich hier die Bezeichnung der Artikelgruppe "Haushalt" auf "Haushaltswaren" geändert. Die Artikelgruppe "SP Spielwaren" kommt hier gar nicht mehr vor, D.h. genau diese Änderungen müssen nach einem Abgleich in die Tabelle "artikelgruppen" eingearbeitet werden. Ohne MERGE müssten wir drei einzelne Anweisungen verwenden, ein Insert, ein Update und Delete, um diese Aufgaben zu bewerkstelligen. Betrachten wir uns diese Einzelanweisungen vorweg. Zuerst die Änderungen einarbeiten, das bedeutet, der Text der Artikelgruppe "Haushalt" soll auf "Haushaltswaren" geändert werden. Dazu benötigen wir ein synchronisiertes Update. Dieses wird bei Oracle mit synchronisierten Unterabfragen realisiert. Im konkreten Fall benötige ich hier zwei Unterabfragen. Einerseits ändere ich in der Tabelle "artikelgruppen" den Text dahingehend, dass ich sage: "Hol mir über dieses synchronisierte Unterabfrage jene Bezeichnung aus der Tabelle 'gruppen1', bei der die ID dem Artikelgruppenkürzel des aktuellen Datensatzes entspricht." Ich möchte aber nicht alle Daten überschreiben, auch wenn sie nicht geändert sind, sondern nur die tatsächlichen Änderungen. Deshalb verwende ich eine zweite synchronisierte Unterabfrage in der WHERE-Klausel, um zu bestimmen, welche Artikelgruppen sind überhaupt geändert worden. Wenn ich diese Anweisung also markiere und alleine ausführe, dann bekomm ich heraus die ID von "Haushalt", weil nur "Haushalt" geändert worden ist. Über diesen "JOIN" definier ich alle und ich sage, wo hat sich eine Änderung ergeben, wo ist der Text in der einen Tabelle unterschiedlich von der Bezeichnung in der anderen? Wenn ich diese Anweisung ausführe, habe ich eine Zeile aktualisiert. Zur Kontrolle sehen wir, dass sich der Inhalt hier geändert hat. Anstelle von "Haushalt" heißt die Gruppe jetzt "Haushaltswaren". Mit der nächsten Anweisung werden die zwei neuen Artikelgruppen "Bücher" sowie "Blu-ray Discs" ergänzt. Dazu verwende ich diese Select-Anweisung mit einem Outer-Join, um alles zu filtern, was es in der einen Tabelle gibt und in der anderen nicht. Betrachten wir uns die Daten vorweg. Wir sehen, dieses Select-Statement liefert diese zwei Zeilen und die werden kombiniert mit dem Insert in die Tabelle "artikelgruppen" eingefügt. Kontrollieren wir das Ergebnis. Nun sehen wir auch hier diese zwei Einträge. Letztendlich möchten wir jene Daten löschen, die in der Tabelle nicht mehr enthalten sind, D.h. mit dieser Löschanweisung über die Unterabfrage holen wir uns alle IDs aus der Tabelle "artikelgruppen". Alle, die in dieser Liste nicht mehr enthalten sind, sollen gelöscht werden. Ich führe diese Anweisung aus, eine Zeile gelöscht, D.h. die Kontrolle wird zeigen, dass es die "Spielwaren" nun in der Tabelle "artikelgruppen" nicht mehr gibt. Wir haben also gesehen, dass wir drei einzelne Anweisungen benötigen, um diese zwei Datenbestände abzugleichen. Diese kann man nun mit einem MERGE-Statement zusammenfassen. Bevor ich das realisiere, werde ich die Daten wieder zurücksetzen. Dazu habe ich die Tabelle "gruppen2" vorbereitet. Die Tabelle "gruppen2" ist ein Abbild der Tabelle "gruppen1". Nur inhaltlich entspricht sie der Ursprungsvariante der Tabelle "artikelgruppen". D.h., wenn ich dieselben Anweisungen, die ich jetzt mit der "gruppen1" durchgeführt habe, nun mit "gruppen2" ausführe, habe ich wieder den Ursprungszustand hergestellt. Das mache ich jetzt schnell. Ich tausche hier "gruppen2" durch "gruppen1" jeweils aus und starte diese Anweisungen, damit ich wieder meinen Ursprungszustand hergestellt habe. Letztendlich auch hier wieder noch das Delete und zur Kontrolle in der Tabelle "artikelgruppen" haben wir jetzt wieder unseren ursprünglichen Zustand. Die Artikelgruppe heißt wieder "Haushalt", "Spielwaren" sind wieder da, "Bücher" und "Blu-ray Discs" sind wieder verschwunden. Wie funktioniert nun die MERGE-Anweisung? Die ursprüngliche MERGE-Anweisung existiert bei Oracle ab der Version 9.i. Ab der Version 10.g gibt's eine Erweiterung. Der Unterschied liegt darin, dass in der Ursprünglichen das Löschen, Delete, noch nicht implementiert gewesen ist. Also dieser dritte Teilschritt, der musste manuell realisiert werden. Betrachten wir uns nun die MERGE-Anweisung. Bei der MERGE-Anweisung muss ich immer eine Ziel- und eine Herkunftstabelle angeben. "INTO" ist meine Zieltabelle in dem Fall "wawi.artikelgruppen". Über die Klausel "USING" gebe ich die Herkunftstabelle ein, in dem Fall ist das meine Tabelle "wawi.gruppen1". Ich muss natürlich definieren, wie diese gejoined wird, ähnlich wie bei einem klassischen Join definiere ich eine Join-Bedingung. Damit ich das hier sauber realisieren kann, vergebe ich hier auch Aliasnamen. "G" für die Gruppen und "M" für "M" wie "Merge" für die Daten, die ich hineinmergen möchte. Die Bedingung lautet eben, dass die "g.artgr" entspricht der "m.id". Nun muss ich hier definieren, was passiert, wenn es einen Treffer, also eine Übereinstimmung gibt und was, wenn es keine Übereinstimmung gibt. Das geht über die Bedingung "WHEN MATCHED THEN". Dann wird definiert, was geschehen soll, wenn es eine Übereinstimmung zwischen Ziel und Herkunft gibt. Über das Gegenteil, also "WHEN NOT MATCHED THEN" wird definiert, was passiert, wenn es keine Übereinstimmung gibt. Bei der ersten Variante passiert das hier, dass ich ein Update der Bezeichnung durchführe für den Fall, dass sie unterschiedlich ist. Die Syntex lautet "UPDATE SET". Die Zielspalte in der Zieltabelle wäre "g.grtext" und die soll überschrieben werden mit "m.bezeichnung", also in der MERGE-Tabelle der Bezeichnung. Allerdings sollen nicht alle überschrieben werden, sondern nur jene, die sich geändert haben. Dazu kann ich in der Oracle-Syntex hier eine WHERE-Klausel noch ergänzen: "WHERE (g.grtext ! = m.bezeichnung)", also nur jene, wo es keine Übereinstimmung gibt. Damit auch wirklich nur jene geändert werden, die unterschiedlich sind. Das macht auch Sinn. Für den Fall, dass in der Zieltabelle der Eintrag nicht vorhanden ist, soll er mit Insert eingefügt werden. Also "INSERT", in der Spalte "(artgr, grtext), die Werte "VALUES (m.id, m.bezeichnung). Führen wir also diese Variante hier einmal aus. Ah, hier hab ich einen Tippfehler eingebaut "gr" statt "g" als Präfix hier, das muss ich natürlich ausbessern. Jetzt verschwinden auch diese roten Linien hier und ich starte die Anweisung erneut. Zuerst leere ich die Skriptausgabe aus, damit ich diese Fehlermeldung nicht mehr sehen muss. Jetzt sagt er mir, drei Zeilen zusammengeführt. Bis auf das Delete sind ja alle Vorgänge hier realisert worden. D.h. wir haben hier einerseits zwei neue Zeilen eingefügt und einerseits den Text hier geändert. Betrachten wir uns das Ergebnis. Dann sehen wir, dass nun die zwei Zeilen "Blu-ray Discs" eingefügt worden sind und die Bezeichnung von "Haushalt" auf "Haushaltswaren" geändert worden ist. Ich mach meine Änderungen wieder rückgängig, damit ich wieder den ursprünglichen Datenbestand habe. Kontrolle, wir haben jetzt alles wieder zurückgesetzt. Ab der Version 10.g gibt es hier nämlich eine Erweiterung. Hier kann nämlich nun auch das Löschen nicht mehr vorhandener Daten realisiert werden. Ich kopiere mir dazu diese paar Zeilen 10.g, die können wir auch löschen. So, was ändert sich hier jetzt? Ich kann jetzt hier zusätzlich in der WHEN-MATCHED-Tabelle eine Delete-Anweisung, und zwar nur hier einbauen. Delete und eine entsprechende Bedingung. Allerdings müssen wir jetzt bei der Oracle-Syntex darauf achten, dass ein Delete unter "WHEN MATCHED" zu finden ist, D.h. wir müssen unsere Anweisung so umbauen, dass die, die zu löschen sind, in der Ursprungstabelle gefunden werden. Das werden sie ja nicht, weil sie sollen ja deshalb gelöscht werden in unserem Beispiel, weil sie in der Ursprungstabelle nicht mehr enthalten sind. Deshalb müssen wir uns mit einem kleinen Trick behelfen. Ich habe dazu folgendes Select-Statement vorbereitet. Führen wir es einmal aus und analysieren wir die Anweisung sowie das Ergebnis. Ich habe hier die Artikelgruppen-Tabelle mit der gruppen1-Tabelle mittels "FULL OUTER JOIN" realisiert. Warum? Ich möchte mir für meine MERGE eine Tabelle erzeugen, die einerseits alle vorhandenen Daten mit Änderungen so wie "Haushalt" aber auch die neuen und nicht mehr vorhandenen enthält. Ich brauche einerseits einen Right Outer Join, damit hier im Ergebnis die zwei neuen, nämlich die "Blu-ray Disks" und die "Bücher" dargestellt werden. Aber ich benötige auch einen Left Outer Join, damit die nicht mehr vorhandenen Spielwaren in meiner MERGE-Tabelle zu sehen sind. Weil nur dann können sie im Punkt "WHEN MATCHED" gefunden werden und dann das Löschen vorgenommen werden. Deshalb realisiere ich einen Full Auto Join. Für den Fall, dass in der Tabelle "artikelgruppen" nämlich die Spalten nicht mehr vorkommen, definiere ich ein Lösch-Kennzeichen, z.B. die Raute hier. D.h. generell, verwende ich hier in meinem Select die ID und die Bezeichnung, der zu mergenden Tabelle. Für diesen Fall hier, dass dieser Null ist, nämlich weil in der Tabelle nicht mehr enthalten ist, verwend ich aber das ursprüngliche Artikelgruppen-Kürzel. Damit kommt es zu einem Match. Damit ich später dann die Löschbedingungen definieren kann, muss ich in der Spalte "Bezeichnung", die ja Null ist und nicht gefunden wird, irgendeinen Ersatzwert eintragen, ebenso mit der [Unverständlich] Funktion. Dafür hab ich jetzt hier die Raute definiert. Ich habe hier außerdem Aliasnamen definiert. Das hab ich hier noch vergessen, "AS id" muss ich auch noch hier eintragen. Hier hab ich bereits "bez" für die Bezeichnung definiert, damit ich das als Unterabfrage in meiner MERGE-Anweisung einbauen kann. Diese Anweisung verwende ich nun hier in meiner MERGE-Anweisung anstelle der Ursprungstabelle "wawi.gruppen". Das ist dasselbe wie die Tabelle "wawi.gruppen", aber zusätzlich aufgefettet, um die Werte, die in der Zieltabelle "artikelgruppen" nicht mehr enthalten sind. Eine Unterabfrage wird klassisch in runden Klammern hier eingefügt, das mach ich hier auch. Ich füge sie ein und nehme entsprechend die Einrückung vor, damit das Ganze hier auch optisch sauber dargestellt wird, und lösche die Zeichen, die ich hier nicht mehr benötige, heraus. Habe also jetzt hier diese Unterabfrage verwendet. Was ändert sich jetzt hier? Ich muss nur aufpassen, ich habe hier Kürzel "bez" für diese Spalten genommen. Das muss ich natürlich mit aufnehmen, damit wir keinen Fehler bekommen. Jetzt muss ich für das Delete meine Bedingung setzen, nämlich ich möchte jene löschen in der Zieltabelle, bei denen in der Ursprungstabelle diese Raute enthalten ist. Konkret wären das hier eben die "Spielwaren". Also, "WHERE m.bez" ist gleich, und ich verwende hier die Raute, um das Ganze zu definieren. Und nun hab ich auch das Löschen hier implementiert und mit abgewickelt. Ich starte diese Anweisung und bekomme jetzt die Meldung "4 Zeilen zusammengeführt". D.h., diesmal sind alle Änderungen durchgeführt worden. Kontrollieren wir das, ich führe diese Select-Anweisung aus und wir sehen nun, dass jetzt sowohl die zwei neuen Datensätze eingefügt worden sind, als auch die Änderungen an dem einen vorgenommen worden ist, also dass die "Spielwaren" entfernt worden sind. D.h. diese Anweisung hat jetzt ein komplettes Merge hier implementiert. Möglich erst ab der Version 10.g., weil vorher das Delete nicht implementiert gewesen ist. Um hier schnell das Ganze zurückzusetzen, verwende ich einfach die Anweisung mit der Tabelle 2, und zwar tausch ich hier einfach "gruppen1" durch "gruppen2" aus. Damit müsste genau das Gegenteil realisiert werden. Wenn Sie sich die Videos über das Thema "Transaktionsstarren" schon angesehen haben, könnten Sie natürlich auch mittels Roadback das Rücksetzen bewerkstelligen. Ich starte nun diese Anweisung und wenn wir das Ergebnis betrachten, haben wir nun wieder den Urzustand hergestellt in der Tabelle "artikelgruppen" finden sich wieder die neuen Sätze, die "Spielwaren" sind wieder da. "Bücher" und "Blu-rays" sind entfernt und die Artikelgruppe "HH" heißt wieder "Haushalt". Sie haben in diesem Video gesehen, wie die Syntax der MERGE-Anweisung bei Oracle implementiert ist. Generell verfügbar ist sie ab der Version 9.i, hier aber nur mit der Erstvariante eines Inserts und Updates. Das Löschen nicht mehr enthaltener Datensätze ist hier noch nicht implementiert. Dies ist erst ab der Version 10.g möglich. Um ein Merge durchzuführen, müssen Sie eine Zieltabelle und eine Ursprungstabelle angeben. Wenn Sie in der Ursprungstabelle nicht mehr enthaltene Werte löschen müssen, müssen Sie die Ursprungstabelle durch eine Unterabfrage ersetzen, die mittels "Auto Join" auch jene anzeigt, die nicht mehr enthalten sind. Denn das Löschen ist bei Oracle nur im MERGE-Block implementiert, D.h. in der Ursprungstabelle muss diese Bedingung nachvollziehbar sein. Deshalb haben wir diese Unterabfrage hier verwendet, die mittels Full Auto Join alle Daten, auch die, die zu löschen sind, enthält. Damit kann ich im Block "WHEN MATCHED" hier definieren, welche geändert und welche gelöscht werden. Wichtig ist beim "MATCHED" beim Ändern eine WHERE-Bedingung, damit nicht alle überschrieben werden, auch wenn es gar keine Änderung gibt. "WHEN NOT MATCHED" fügt die neuen vorhandenen Datensätze ein. Nach diesem MERGE, nach dieser Anweisung haben wir einen kompletten Abgleich zwischen den Daten realisiert.

SQL Grundkurs 1: Die Sprache erlernen

Arbeiten Sie sich in die Grundlagen der Datenbanksprache SQL am Beispiel von Microsoft SQL Server, Oracle und MySQL ein und lassen Sie sich die praktische Nutzung erklären.

14 Std. 40 min (112 Videos)
Derzeit sind keine Feedbacks vorhanden...
 

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!