Das Verarbeiten größerer Datenmengen in einem einzelnen DML-Statement birgt einen kapitalen Stolperstein: Ein einziger, fehlerhafter Datensatz führt zum Abbruch der gesamten Transaktion und dem damit verbundenen Zurückrollen aller bereits erfolgreich verarbeiteten Datensätze. In vielen Fällen ist es jedoch vollkommen akzeptabel eine kleinere Menge an fehlerhaften Datensätzen abzuweisen und den fehlerfreien Anteil trotzdem zu behalten.
Häufig wird dieses Problem entweder durch Einzelsatzverarbeitung oder durch Verwendung von BULK-Operationen und SAVE EXCEPTIONS gelöst. Ersteres ist aus Performance-Sicht in der Regel nicht zu empfehlen, zweiteres ist zwar sehr schnell aber unter Umständen auch mit erheblich komplexeren Code verbunden.
Oracle bietet jedoch auch eine dritte Lösung die ggf. den idealen Mittelweg bietet. Für alle DML-Befehle kann ein automatisches Fehlerlogging, inklusive der Möglichkeit fehlerhafte Datensätze innerhalb einer Transaktion zu überspringen, aktiviert werden. Die Grundlage dafür stellt das Package dbms_errlog dar.
Zunächst wird für die Zieltabelle der DML-Operation eine passende Fehlertabelle erstellt. Dies kann mit folgendem Beispielcode realisiert werden.
BEGIN
dbms_errlog.create_error_log(
dml_table_name => '<ZIELTABELLE>',
err_log_table_name => '<FEHLERLOGTABELLE>',
skip_unsupported => true
);
END;
Oracle erstellt damit eine Loggingtabelle mit frei wählbarem Namen. Diese enthält alle Attribute der eigentliche Zieltabelle (hier jedoch immer mit dem Datentypen VARCHAR2(4000)) sowie zusätzliche Spalten u.a. für Fehlercode, Fehlermeldung und ROWID. Um diese nun auch zu verwenden, muss die jeweilige DML-Anweisung geringfügig erweitert werden.
INSERT INTO <ZIELTABELLE>
SELECT *
FROM <QUELLTABELLE>
log errors into <FEHLERLOGTABELLE> ('<TAG>')
reject limit <ANZAHL>
Die hinter reject limit angegebene Anzahl bestimmt nun, wie viele Fehler bei der Verarbeitung der DML-Operation geduldet werden. Ist die Anzahl der tatsächlich auftretenden Fehler geringer als das angegebene Limit, werden für abgewiesene Datensätze Log-Einträge erzeugt. Fehlerfreie Datensätze werden verarbeitet. Erst wenn die Anzahl der Fehler das Limit übersteigt wird die gesamte Transaktion zurückgerollt. Der Inhalt der Fehlertabelle bleibt dabei natürlich erhalten, sie wird in einer autonomen Transaktion von der Oracle-Datenbank automatisch gepflegt.
Bleibt noch die Bedeutung das Parameters TAG zu klären: Hierbei handelt es sich quasi um ein Freitextfeld, welches 1:1 in das Feld ORA_ERR_TAG$ der Fehlerlogtabelle übernommen wird. Es kann genutzt werden um Fehlermeldungen einer DML-Operation zuordnen zu können, bei täglichen laufenden Importen könnte man hier z.B. einen Timestamp und den Namen des Imports mitgeben.
Mit Error Logging lassen sich also ohne großen Aufwand Fehler in DML-Operationen protokollieren und gleichzeitig fehlerhafte Datensätze komfortabel überspringen. Ein Punkt sollte jedoch beachtet werden: Die beschriebene Methode unterstützt keine LOB-Datentypen.