MERGE vereint die Funktionen INSERT und UPDATE in einem Arbeitsgang. Abhängig vom Ergebnis der Bedingung in der ON-Klausel ändert MERGE Spaltenwerte von bereits existierenden Sätzen (WHEN MATCHED THEN) oder fügt neue Sätze in eine bestehende Tabelle ein (WHEN NOT MATCHED THEN).
Die Bedingung kann dabei von einer einfachen Existenzabfrage bis hin zu komplexen Suchkriterien reichen. Auch triviale Bedingungen (z.B 1 <> 1
) sind möglich; sie führen dazu, dass nur Sätze geändert bzw. neu eingefügt werden.
Die in der MERGE-Anweisung (und in Voreinstellungen) vorkommenden Spezial-Literale (siehe "Spezial-Literale") sowie die Zeitfunktionen CURRENT_DATE, CURRENT_TIME und CURRENT_TIMESTAMP werden einmal ausgewertet und die berechneten Werte gelten für alle Einfügungen.
Sind für die Tabelle bzw. die betroffenen Spalten Integritätsbedingungen definiert, werden diese nach dem Einfügen oder Ändern geprüft. Ist eine Integritätsbedingung verletzt, werden die Einfügungen und Änderungen rückgängig gemacht und ein entsprechender SQLSTATE gesetzt.
Zur erfolgreichen Ausführung der MERGE-Anweisung müssen bestimmte Voraussetzungen erfüllt sein:
Zum Einfügen oder Ändern von Sätzen in tabelle müssen Sie
Eigentümer von tabelle sein oder
wenigstens das INSERT-Privileg besitzen, wenn satz_einfuegen angegeben ist oder
wenigstens das UPDATE-Privileg für alle Spalten besitzen, die in satz_ändern geändert werden, wenn satz_ändern angegeben ist.
Außerdem müssen Sie das SELECT-Privileg für alle Tabellen besitzen, die in tabellenangabe angesprochen werden.
Der Transaktionsmodus der aktuellen Transaktion muss READ WRITE sein.
MERGE INTO
tabelle [[AS]
korrelationsname ]
USING
tabellenangabe
ON
suchbedingung
{ WHEN MATCHED THEN
satz_ändern |
WHEN NOT MATCHED THEN
satz_einfügen }...
satz_ändern ::= UPDATE SET
spalte =
spalten-wert [,
spalte =
spalten-wert ]...
spalten-wert ::= {
ausdruck | DEFAULT | NULL}
satz_einfügen ::= INSERT [(
spalte ,...)] [COUNT INTO
spalte ] VALUES(
wert [
,wert ]
... )
wert ::= {
ausdruck | NULL | DEFAULT | * }
tabelle
Name der Zieltabelle, in die Sätze eingefügt oder in der Sätze geändert werden sollen. Die Zieltabelle kann eine Basistabelle oder ein änderbarer View sein.
Sie darf keine multiplen Spalten besitzen (siehe Hinweis auf "MERGE - Sätze in Tabelle einfügen oder Spaltenwerte ändern").
korrelationsname
Tabellenname, der innerhalb dieser Anweisung eine Umbenennung für tabelle ist.
Bei jeder Spaltenangabe, die sich auf tabelle bezieht, müssen Sie den Spaltennamen mit dem neuen Namen korrelationsname qualifizieren, wenn der Spaltenname nicht eindeutig ist.
Der neue Name muss eindeutig sein, d.h. korrelationsname darf nur einmal in einer Tabellenangabe dieser Anweisung vorkommen.
Sie müssen eine Tabelle umbenennen, wenn die Spalten der Tabelle ohne Umbenennung nicht eindeutig angegeben werden können.
Außerdem können Sie eine Tabelle umbenennen, um durch entsprechende Namen einen Ausdruck verständlicher zu formulieren oder um lange Namen abzukürzen.
USING tabellenangabe
Angabe einer Quelltabelle (ungleich der Zieltabelle tabelle), unter deren Verwendung Sätze in die Zieltabelle tabelle eingefügt oder Sätze in der Zieltabelle tabelle geändert werden sollen. Sie darf keine multiplen Spalten besitzen (siehe Hinweis auf "MERGE - Sätze in Tabelle einfügen oder Spaltenwerte ändern"). Innerhalb der tabellenangabe darf auch die Zieltabelle tabelle referenziert werden.
ON suchbedingung
Angabe der Bedingung, die entscheidet, ob die UPDATE-Klausel ausgeführt werden soll (Resultat: TRUE) oder ob die INSERT-Klausel ausgeführt werden soll (Resultat: FALSE).
Genauer gesagt wird für jeden Satz der Quelltabelle geprüft, ob es einen Satz in der Zieltabelle gibt, so dass für die Kombination dieser beiden Sätze die suchbedingung wahr ist.
Wenn es keinen derartigen Satz in der Zieltabelle gibt, dann wird die INSERT-Klausel ausgeführt, d.h. der Satz der Quelltabelle wird in die Zieltabelle eingefügt. Wenn es einen oder mehrere derartige Sätze in der Zieltabelle gibt, dann wird für jeden dieser Sätze die UPDATE-Klausel ausgeführt, d.h. die entsprechenden Sätze in der Zieltabelle werden geändert.
Zwei verschiedene Sätze der Quelltabelle dürfen nicht zu Änderungen des gleichen Satzes in der Zieltabelle führen (Mehrfachänderung), sonst wird die MERGE-Anweisung mit SQLSTATE abgebrochen.
WHEN MATCHED THEN satz_ändern
Ein zu ändernder Satz wurde gefunden.
UPDATE SET ...
Angaben zum Update des zu ändernden Satzes.
Zur Beschreibung der Parameter spalte, ausdruck, DEFAULT
und NULL
siehe die entsprechenden Beschreibungen in der SQL-Anweisung UPDATE auf "UPDATE - Spaltenwerte ändern". Ein zu ändernder Satz darf nur einmal geändert werden. Eine weitere Änderung wird mit SQLSTATE abgewiesen.
Bei partitionierten Tabellen darf der Primärschlüsselwert nicht geändert werden.
WHEN NOT MATCHED THEN satz_einfügen
Es wurde kein entsprechender Satz gefunden. Der neue Satz soll eingefügt werden.
INSERT ...
Angaben zum Einfügen des neuen Satzes.
(spalte,...)
Zählt die Spalten auf, deren Werte in der INSERT-Klausel der MERGE-Anweisung angegeben werden, und legt die Reihenfolge dafür fest. Die Werte der restlichen Spalten des einzufügenden Satzes werden nicht in der MERGE-Anweisung angegeben, sondern sind DEFAULT-, NULL- oder von SESAM/SQL bestimmte Werte.
Zur Beschreibung des Parameters spalte siehe die entsprechende Beschreibung in der SQL-Anweisung INSERT auf "INSERT - Sätze in Tabelle einfügen".
Keine spaltenliste angegeben:
Die MERGE-Anweisung gibt für alle Spalten der Zieltabelle tabelle die Werte des einzufügenden Satzes an, außer für die mit COUNT INTO angegebenen Spalte, und zwar in der Spaltenreihenfolge, die mit CREATE TABLE und ALTER TABLE bzw. mit CREATE VIEW festgelegt wurde.
COUNT INTO spalte
Siehe die entsprechende Beschreibung in der SQL-Anweisung INSERT auf "INSERT - Sätze in Tabelle einfügen".
VALUES (...)
Die benötigten Spaltenwerte sind für den einzufügenden Satz angegeben.
Zur Beschreibung von ausdruck, NULL
, DEFAULT
und *
siehe die Beschreibung zu iinsert_ausdruck_1 in der SQL-Anweisung INSERT auf "INSERT - Sätze in Tabelle einfügen".
In ausdruck dürfen Sie keine Tabelle angeben, die sich auf die Zieltabelle, in die die neuen Sätze eingefügt werden, bezieht.
Insbesondere dürfen Sie sich auf keine Spalte der Zieltabelle beziehen.
Die Anzahl der Spalten der VALUES-Klausel muss gleich der Anzahl der Spalten sein, die gemäß den Angaben bei (spalte,...) und COUNT INTO anzugeben sind. Die i-te Spalte der Zieltabelle enthält die Werte für die i-te Spaltenangabe in (spalte,...) (falls (spalte,...) angegeben ist), bzw. für die i-te Spalte von tabelle, wobei eine mit COUNT INTO angegebene Spalte von tabelle nicht mitgezählt wird.
Für diese Zuweisungen gelten die im Abschnitt „Werte in Tabellenspalten eintragen" angegebenen Zuweisungregeln.
Die restlichen Spalten des eingefügten Satzes werden folgendermaßen gesetzt:
Die mit COUNT INTO angegebene Spalte wird auf einen von SESAM/SQL bestimmten Wert gesetzt.
Eine Spalte mit Voreinstellung wird auf den voreingestellten Wert (DEFAULT) gesetzt.
Eine Spalte ohne Voreinstellung wird auf den NULL-Wert gesetzt.
Wenn die Zieltabelle tabelle ein View ist, dann werden die Sätze in die zugrunde liegende Basistabelle eingefügt; die Spalten der Basistabelle, die nicht im View enthalten sind, werden ebenso gesetzt.
Werte für multiple Spalte einfügen
Basistabellen mit multiplen Spalten können in der MERGE-Anweisung nicht direkt bearbeitet werden.
MERGE und Integritätsbedingungen
Durch Angabe von Integritätsbedingungen bei der Definition der Basistabelle können Sie den Wertebereich für die entsprechenden Spalten einschränken. Die in der MERGE-Anweisung angegebenen Werte müssen den definierten Integritätsbedingungen genügen, sonst wird die MERGE-Anweisung mit SQLSTATE abgebrochen.
MERGE und Transaktionssicherung
MERGE leitet außerhalb von Routinen eine SQL-Transaktion ein, wenn keine Transaktion offen ist. Durch die Definition eines Isolationslevels bei konkurrierenden Transaktionen können Sie steuern, welche Auswirkungen die MERGE-Anweisung auf diese Transaktionen hat (siehe Abschnitt „SET TRANSACTION - Transaktionseigenschaften festlegen").
Tritt während der MERGE-Anweisung ein Fehler auf, so werden sämtliche, durch die MERGE-Anweisung bereits durchgeführten Änderungen rückgängig gemacht.
Beispiele
Folgendes Beispiel dient der Bestandsverwaltung beim Eintreffen einer neuen Lieferung.
Bei den bereits vorhandenen Artikeln mit demselben Preis wird der Lagerbestand in der Bestandstabelle aktualisiert. Neue Artikel der Lieferungstabelle werden der Bestandstabelle hinzugefügt.
MERGE INTO bestand AS b USING lieferung AS l ON b.artikel_nr = l.artikel_nr AND b.artikel_preis = l.artikel_preis WHEN MATCHED THEN UPDATE SET artikel_anz = b.artikel_anz + l.artikel_anz WHEN NOT MATCHED THEN INSERT (artikel_nr,artikel_preis,artikel_anz) VALUES (l.artikel_nr,l.artikel_preis,l.artikel_anz)
Folgendes komplexe Beispiel dient ebenfalls der Bestandsverwaltung beim Eintreffen einer neuen Lieferung. Die Daten der neuen Lieferung werden z.B. in der CSV-Eingabedatei LIE-FERUNG.DATA (mit einer Überschriftszeile) geliefert:
Artikelnummer,Menge,Preis 1, 4, 18.50 2, 11, 19.90 3, 0, 22.95 4, 3, 84.30 5, 7, 25.90
Folgende MERGE-Anweisung aktualisiert die Tabelle bestand für die bereits vorhandenen Artikel. Neue Artikel der Lieferung werden der Bestandstabelle hinzugefügt. Die Überschriftszeile der CSV-Datei wird durch die Klausel WITH ORDINALITY in Verbindung mit WHERE übersprungen
MERGE INTO bestand USING (SELECT CAST(artikelnummer as INT), CAST(menge as INT), CAST(neuerpreis as NUMERIC(10,2)) FROM TABLE(CSV('LIEFERUNG.DATA' DELIMITER ',' QUOTE '"' ESCAPE '\', varchar(30), varchar(40), varchar(50))) WITH ORDINALITY AS T(artikelnummer, menge, neuerpreis, counter) WHERE counter > 1) AS lieferung(artikelnummer, menge, neuerpreis) ON bestand.artikelnummer = lieferung.artikelnummer WHEN MATCHED THEN UPDATE SET menge = bestand.menge + lieferung.menge, preis = lieferung.neuerpreis WHEN NOT MATCHED THEN INSERT (artikelnummer, menge, preis) VALUES(lieferung.artikelnummer, lieferung.menge, lieferung.neuerpreis)
Siehe auch
DELETE, INSERT, UPDATE