Implementieren der strukturierten Ausnahmebehandlung

Abgeschlossen

Da Sie nun die Art von Fehlern und die grundlegende Fehlerbehandlung in T-SQL verstehen, ist es an der Zeit, eine komplexere Form der Fehlerbehandlung zu betrachten. Die strukturierte Ausnahmebehandlung wurde in SQL Server 2005 eingeführt.

Hier erfahren Sie, wie Sie es verwenden und deren Vorteile und Einschränkungen auswerten, einschließlich des TRY CATCH-Blocks, der Rolle der Fehlerbehandlungsfunktionen und des Verständnisses des Unterschieds zwischen abfangbaren und nicht verketteten Fehlern. Schließlich sehen Sie, wie Fehler bei Bedarf verwaltet und angezeigt werden können.

Was ist TRY/CATCH-Blockprogrammierung?

Die strukturierte Ausnahmebehandlung ist leistungsstärker als die Fehlerbehandlung basierend auf der @@ERROR Systemvariable. Sie können verhindern, dass Code mit Fehlerbehandlungscode verworfen wird, und diesen Fehlerbehandlungscode zentralisieren. Die Zentralisierung des Fehlerbehandlungscodes bedeutet auch, dass Sie sich mehr auf den Zweck des Codes konzentrieren können, anstatt auf die darin enthaltene Fehlerbehandlung zu achten.

TRY-Block und CATCH-Block

Bei Verwendung der strukturierten Ausnahmebehandlung wird Code, der möglicherweise einen Fehler auslöst, in einem TRY-Block platziert. TRY-Blöcke werden von BEGIN TRY- und END TRY-Anweisungen eingeschlossen.

Sollte ein catchabler Fehler auftreten – die meisten Fehler können abgefangen werden, wird die Ausführungskontrolle in den CATCH-Block verschoben. Der CATCH-Block ist eine Reihe von T-SQL-Anweisungen, die von BEGIN CATCH- und END CATCH-Anweisungen eingeschlossen werden.

Hinweis

Während BEGIN CATCH und END TRY separate Anweisungen sind, muss BEGIN CATCH sofort dem END TRY folgen.

Aktuelle Einschränkungen

Sprachen auf hoher Ebene bieten häufig ein Try/catch/finally-Konstrukt und werden häufig verwendet, um Ressourcen implizit freizugeben. Es gibt keinen entsprechenden FINALLY-Block in T-SQL.

Verstehen des Unterschieds zwischen abfangbaren und nicht verketteten Fehlern

Es ist wichtig zu erkennen, dass Sie zwar mit TRY/CATCH-Blöcken einen viel breiteren Bereich von Fehlern abfangen können, als sie mit @@ERROR möglich sind, aber sie können nicht jeden Typ abfangen.

Catchable vs. nicht verkettete Fehler

Nicht alle Fehler können von TRY/CATCH-Blöcken innerhalb desselben Bereichs erfasst werden, in dem der TRY/CATCH-Block vorhanden ist. Häufig können Fehler, die nicht in demselben Bereich erfasst werden können, in einem umgebenden Bereich abgefangen werden. Beispielsweise können Sie einen Fehler in der gespeicherten Prozedur, die den TRY/CATCH-Block enthält, nicht abfangen. Sie werden diesen Fehler jedoch wahrscheinlich in einem TRY/CATCH-Block im Code abfangen, der die gespeicherte Prozedur aufgerufen hat, in der der Fehler aufgetreten ist.

Häufige nicht vercatchierbare Fehler

Häufige Beispiele für nicht verkettete Fehler sind:

  • Kompilierungsfehler, z. B. Syntaxfehler, die verhindern, dass ein Batch kompiliert wird.
  • Neukompilierungsprobleme auf Anweisungsebene, die in der Regel mit der Auflösung verzögerter Namen zusammenhängen. Sie können beispielsweise eine gespeicherte Prozedur erstellen, die sich auf eine unbekannte Tabelle bezieht. Ein Fehler wird nur ausgelöst, wenn die Prozedur versucht, den Namen der Tabelle in eine Objekt-ID aufzulösen.

So wird's gezeigt, wie Fehler mithilfe von THROW erneut ausgelöst werden

Wenn die THROW-Anweisung in einem CATCH-Block ohne Parameter verwendet wird, wird der Fehler erneut ausgelöst, der dazu führte, dass der Code den CATCH-Block eingibt. Sie können diese Technik verwenden, um die Fehlerprotokollierung in der Datenbank zu implementieren, indem Sie Fehler erfassen und deren Details protokollieren und dann den ursprünglichen Fehler an die Clientanwendung auslösen, damit sie dort behandelt werden kann.

Hier ist ein Beispiel für das Erneute Auslösen eines Fehlers.

BEGIN TRY
    -- code to be executed
END TRY
BEGIN CATCH
    PRINT ERROR_MESSAGE();
    THROW
END CATCH

In einigen früheren Versionen von SQL Server gab es keine Methode zum Auslösen eines Systemfehlers. Während THROW keinen Systemfehler angeben kann, der ausgelöst werden soll, wenn THROW ohne Parameter in einem CATCH-Block verwendet wird, wird sowohl System- als auch Benutzerfehler erneut angezeigt.

Was sind Fehlerbehandlungsfunktionen?

CATCH-Blöcke stellen die fehlerbezogenen Informationen während der gesamten Dauer des CATCH-Blocks zur Verfügung. Dazu gehören Unterscopes, z. B. gespeicherte Prozeduren, die innerhalb des CATCH-Blocks ausgeführt werden.

Fehlerbehandlungsfunktionen

Sie sollten daran erinnern, dass beim Programmieren mit @@ERROR der Wert, der von der systemvariablen @@ERROR gehalten wird, zurückgesetzt wurde, sobald die nächste Anweisung ausgeführt wurde.

Ein weiterer wichtiger Vorteil der strukturierten Ausnahmebehandlung in T-SQL ist, dass eine Reihe von Fehlerbehandlungsfunktionen bereitgestellt wurde und diese ihre Werte im gesamten CATCH-Block beibehalten. Separate Funktionen stellen jede Eigenschaft eines ausgelösten Fehlers bereit.

Dies bedeutet, dass Sie generische fehlerbehandlung gespeicherte Prozeduren schreiben können, die weiterhin auf fehlerbezogene Informationen zugreifen können.

  • CATCH-Blöcke stellen die fehlerbezogenen Informationen während der gesamten Dauer des CATCH-Blocks zur Verfügung.
  • @@Error wird zurückgesetzt, wenn die nächste Anweisung ausgeführt wird.

Verwalten von Fehlern im Code

Die SQL CLR-Integration ermöglicht die Ausführung von verwaltetem Code in SQL Server. Allgemeine .NET-Sprachen, z. B. C# und VB, verfügen über detaillierte Ausnahmebehandlungen. Fehler können mithilfe standardmäßiger .NET try/catch/finally-Blöcke abgefangen werden.

Fehler in verwaltetem Code

Im Allgemeinen möchten Sie Fehler in verwaltetem Code so weit wie möglich abfangen. Es ist jedoch wichtig zu erkennen, dass alle Fehler, die nicht im verwalteten Code behandelt werden, an den aufrufenden T-SQL-Code übergeben werden. Wenn ein Fehler, der in verwaltetem Code auftritt, an SQL Server zurückgegeben wird, scheint es ein Fehler von 6522 zu sein. Fehler können geschachtelt werden, und dieser bestimmte Fehler wird die eigentliche Ursache des Fehlers umschlossen.

Eine weitere seltene, aber mögliche Ursache von Fehlern in verwaltetem Code wäre, dass der Code eine RAISERROR T-SQL-Anweisung über ein SqlCommand-Objekt ausführen könnte.