Die Fehlerbehandlung und die Organisation der Protokollierung in SQL haben mit der Entwicklung komplexer Geschäftsprozesse besondere Bedeutung erlangt, wobei es wichtig wurde, nicht nur die Ausführung bei einem Fehler zu stoppen, sondern auch den Fehler festzuhalten und, wenn möglich, weiterzuarbeiten. Ursprünglich hatte SQL keine ausgefeilten Mittel wie try-catch, und jede DBMS bot ihre eigenen Mechanismen an.
Geschichte des Themas:
Frühere Versionen von SQL-Standards hatten keine integrierten Anweisungen zur Fehlererfassung in Prozeduren. Später begannen Hersteller, Konstrukte wie TRY...CATCH in Microsoft SQL Server oder HANDLER in MySQL zu integrieren, was eine flexiblere Steuerung des Arbeitsprozesses auf der Datenbankebene ermöglichte.
Problem:
Fehler können sowohl durch ungültige Daten als auch aus systemischen Gründen auftreten. Wenn in einer gespeicherten Prozedur keine Erfassung und Aufzeichnung von Fehlern implementiert ist, wird Debugging und Wartung extrem schwierig. Darüber hinaus ist es wichtig, kritische Fehler von verarbeitetem zu unterscheiden, um die Ausführung von Geschäftsoperationen nicht unnötig zu unterbrechen.
Lösung:
In modernen Systemen sollten Konstrukte zur Sammlung und Protokollierung von Fehlern implementiert werden. Es sollten separate Protokolltabellen erstellt, TRY...CATCH (SQL Server) oder DECLARE ... HANDLER (MySQL) verwendet und detaillierte Informationen zu Ausnahmen gespeichert werden, um die Ursachen von Fehlern später zu analysieren.
Beispielcode (SQL Server):
CREATE PROCEDURE dbo.UpdateCustomer @CustomerID INT, @NewName NVARCHAR(100) AS BEGIN BEGIN TRY UPDATE Customers SET Name = @NewName WHERE CustomerID = @CustomerID; END TRY BEGIN CATCH INSERT INTO ErrorLog (ErrorMessage, ErrorSeverity, ErrorTime) VALUES (ERROR_MESSAGE(), ERROR_SEVERITY(), GETDATE()); THROW; END CATCH END;
Wesentliche Merkmale:
Können alle Fehlerarten innerhalb des TRY...CATCH-Blocks (oder über Handler) erfasst werden?
Nein, nicht alle Fehler, z. B. schwerwiegende Serverfehler, können erfasst werden. Fehler wie "Attention" oder Verbindungsabbrüche fallen außerhalb der Transaktionsverarbeitung.
Was geschieht mit nicht festgeschriebenen Änderungen in der Prozedur bei einem Fehler, wenn keine Transaktion verwendet wird?
Die Änderungen werden teilweise festgeschrieben, ein Teil der Aktualisierungen wird in die Datenbank aufgenommen, ein Teil kann verloren gehen. Um Inkonsistenzen zu vermeiden, wird empfohlen, immer Transaktionen zu verwenden.
BEGIN TRY BEGIN TRANSACTION; --...Code COMMIT; END TRY BEGIN CATCH ROLLBACK; END CATCH
Kann man INSERT EXEC direkt aus dem CATCH-Block verwenden, um einen Fehler aus einem anderen Kontext aufzuzeichnen?
Nicht immer: INSERT EXEC ist in einigen Kontexten (z. B. wenn bereits eine aktive Transaktion vorliegt) verboten, also könnte dies Fehler zweiter Ordnung verursachen. Es ist besser, die Fehlerdetails lokal zu sammeln und diese später mit einem einzelnen INSERT aufzuzeichnen.
Der Kunde implementierte die Logik nur über RAISERROR ohne Protokollierung, sodass die Fehler nicht gespeichert und analysiert wurden.
Vorteile:
Nachteile:
TRY...CATCH plus ErrorLog-Tabelle, Protokollierung von Zeit, Fehlercode, Benutzer, Text und Trace.
Vorteile:
Nachteile: