SQL Server 2008: Schnelle Datenbankaktualisierung mit MERGE

(http://www.zdnet.de/magazin/39187480/sql-server-2008-schnelle-datenbankaktualisierung-mit-merge.htm)

von Tim Chapman, 13. März 2008

Mit dem neuen MERGE-Befehl in SQL Server 2008 kann man Daten auf Basis bestimmter Join-Bedingungen mittels einer einzigen Anweisung einfügen, aktualisieren oder löschen. Der Artikel stellt die Funktionsweise der MERGE-Anweisung an einem einfachen Beispiel vor.

In den bisherigen Versionen von SQL Server muss man separate Anweisungen erzeugen, wenn in einer Tabelle, abhängig von den Bedingungen in einer anderen Tabelle, Daten eingefügt, aktualisiert oder gelöscht werden sollen. Mit MERGE lässt sich die Logik für diese Datenmanipulationen in einer einzigen Anweisung unterbringen.

Wie funktioniert MERGE?

Der MERGE-Befehl funktioniert im Grunde wie separate Insert-, Update- und Delete-Anweisungen in einem einzigen Befehl. Man gibt einen Quelldatensatz (Source) und eine Zieltabelle (Target) sowie die Join-Bedingung zwischen beiden an. Dann wird die Art der Datenmanipulation deklariert, die bei erfüllter oder nicht erfüllter Übereinstimmung (Match) zwischen den beiden Datensätzen ablaufen soll. MERGE ist besonders nützlich, wenn es darum geht, Datenlagertabellen zu laden, die sehr groß sind und je nach Zeilenzahl bestimmte Aktionen erfordern.

Ein einfaches Beispiel

Folgendes Beispiel simuliert Eingaben zu Verkäufen. Sie werden in eine Datenbank aufgenommen und dann in eine Berichtstabelle geladen, die die täglichen Verkaufsstatistiken aufzeichnet.

In einem klassischen Szenario würden die Datensätze zuerst in eine Staging-Tabelle (hier: Sales-Feed) geladen. Anschließend würde eine Reihe von Transformationen oder DDL-Anweisungen an der Berichtstabelle (hier: Sales-Archive) ausgeführt, um die täglichen Verkaufsdaten zu aktualisieren.

Mit der MERGE-Anweisung kann die Sales-Archive-Tabelle mittels einer einzigen Anweisung aktualisiert werden, anstatt verschiedene DDL-Anweisungen benutzen zu müssen. Da nur eine anstelle mehrerer Lookup-Operationen durchgeführt wird, lässt sich die Zeit verkürzen, die für die Aktualisierung notwendig ist.

Das folgende Script erzeugt die Tabellen Sales-Archive und Sales-Feed:

Mit dem nächsten Listing werden einige Daten in die Tabelle Sales-Feed geladen. Die Art, in der hier die Daten in die Tabelle eingefügt werden, ist neu in SQL Server 2008. Auf diese Weise lassen sich viele Werte spezifizieren, die dann über die VALUES-Klausel der INSERT-Anweisung eingefügt werden.

In der Tabelle Sales-Feed sind jetzt einige Zeilen mit Daten vorhanden. In der Tabelle Sales-Archive befinden sich jedoch noch keine Daten. Jetzt muss die MERGE-Anweisung erzeugt werden, um Daten zu dieser Tabelle hinzuzufügen.

Auf den ersten Blick sieht das ziemlich kompliziert aus. Wenn man sich aber erst einmal daran gewöhnt hat, ist es nicht mehr so vertrackt. Die Tabelle, die direkt auf die MERGE-Anweisung folgt, ist diejenige, die manipuliert wird. Sie ist also die Zieltabelle.

In der USING-Anweisung werden Daten aus der Sales-Feed-Tabelle in einer Unterabfrage auf Basis der Customer-ID gruppiert. Dieser Teil ist als Quelltabelle bereits bekannt. Die Gruppierung gewährleistet, dass es nur einen Datensatz pro Kunde gibt, mit dem die Tabelle Sales-Archive aktualisiert wird.

In der ON-Klausel der MERGE-Anweisung wird Folgendes angegeben: die Verbindung zwischen der Quelle, der Datengruppierung aus der Unterabfrage und dem Ziel, also der Tabelle Sales-Archive.

In der Klausel WHEN-NOT-MATCHED wird angegeben, was geschehen soll, falls die Datensätze der Quelle nicht im Ziel gefunden werden. In diesem Szenario sollen diese Datensätze in die Tabelle Sales-Archive eingefügt werden.

In der WHEN-MATCHED-Klausel wird festgelegt, was geschehen muss, wenn die Datensätze aus der Tabelle Sales-Archive und der Unterabfrage der Tabelle Sales-Feed gefunden werden. In diesem Beispiel soll aktualisiert werden, was die Tabelle für diesen Tag verzeichnet, etwa die Gesamtsumme aller Verkäufe (TotalSalesAmount), die Anzahl der Verkäufe (TotalSalesCount) und das aktuelle Datum (UpdatedDate).

Wenn eine weitere Verkaufseingabe in die Datenbank gelangt, muss nur noch eine Anweisung ausgeführt werden. Alle neuen Kundenverkäufe werden zur Datenbank hinzugefügt. Zugleich werden alle vorhandenen Verkäufe mit den neuen Verkaufsinformationen aktualisiert.