Implementieren der T-SQL-Fehlerbehandlung

Abgeschlossen

Ein Fehler weist auf ein Problem oder ein bemerkenswertes Problem hin, das während eines Datenbankvorgangs auftritt. Fehler können vom SQL Server-Datenbankmodul als Reaktion auf ein Ereignis oder einen Fehler auf Systemebene generiert werden; oder Sie können Anwendungsfehler in Ihrem Transact-SQL Code generieren.

Elemente von Fehlern der Datenbank-Engine

Unabhängig von der Ursache besteht jeder Fehler aus den folgenden Elementen:

  • Fehlernummer – Eindeutige Nummer, die den spezifischen Fehler identifiziert.
  • Fehlermeldung – Text, der den Fehler beschreibt.
  • Schweregrad – Numerische Angabe der Schwere von 1 bis 25.
  • Status – Interner Zustandscode für die Datenbankmodulbedingung.
  • Prozedur : Der Name der gespeicherten Prozedur oder des Triggers, in dem der Fehler aufgetreten ist.
  • Zeilennummer : Welche Anweisung im Batch oder in der Prozedur den Fehler generiert hat.

Systemfehler

Systemfehler sind vordefiniert, und Sie können sie in der Systemansicht "sys.messages " anzeigen. Wenn ein Systemfehler auftritt, kann SQL Server abhängig vom Schweregrad des Fehlers automatische Abhilfemaßnahmen ergreifen. Wenn beispielsweise ein Fehler mit hohem Schweregrad auftritt, kann SQL Server eine Datenbank offline schalten oder sogar den Datenbankmoduldienst beenden.

Benutzerdefinierte Fehler

Sie können Fehler in Transact-SQL Code generieren, um auf anwendungsspezifische Bedingungen zu reagieren oder informationen anzupassen, die an Clientanwendungen als Reaktion auf Systemfehler gesendet werden. Diese Anwendungsfehler können inline definiert werden, wo sie generiert werden, oder Sie können sie in der Tabelle "sys.messages" zusammen mit den vom System bereitgestellten Fehlern vordefinieren. Die für benutzerdefinierte Fehler verwendeten Fehlernummern müssen 50001 oder höher sein.

Verwenden Sie sp_addmessage, um eine benutzerdefinierte Fehlermeldung zu sys.messages hinzuzufügen. Der Benutzer der Nachricht muss Mitglied der festen Serverrollen „sysadmin“ oder „serveradmin“ sein.

Dies ist die sp_addmessage Syntax:

sp_addmessage [ @msgnum= ] msg_id , [ @severity= ] severity , [ @msgtext= ] 'msg' 
     [ , [ @lang= ] 'language' ] 
     [ , [ @with_log= ] { 'TRUE' | 'FALSE' } ] 
     [ , [ @replace= ] 'replace' ]

Nachfolgend sehen Sie ein Beispiel für eine benutzerdefinierte Fehlermeldung mit dieser Syntax:

sp_addmessage 50001, 10, N’Unexpected value entered’;

Darüber hinaus können Sie benutzerdefinierte Fehlermeldungen definieren, Mitglieder der Sysadmin-Serverrolle können auch einen zusätzlichen Parameter verwenden, @with_log. Wenn dieser Wert auf TRUE festgelegt ist, wird der Fehler auch im Windows-Anwendungsprotokoll aufgezeichnet. Jede in das Windows-Anwendungsprotokoll geschriebene Nachricht wird auch in das SQL Server-Fehlerprotokoll geschrieben. Seien Sie mit der Verwendung der @with_log-Option vorsichtig, da Fachkräfte für die Netzwerk- und Systemadministration Anwendungen nicht schätzen, die sehr viel Daten in die Systemprotokolle schreiben. Wenn der Fehler jedoch von einer Warnung abgefangen werden muss, muss der Fehler zuerst in das Windows-Anwendungsprotokoll geschrieben werden.

Hinweis

Das Auslösen von Systemfehlern wird nicht unterstützt.

Nachrichten können ersetzt werden, ohne sie zuerst zu löschen, indem Sie die @replace Option = 'Ersetzen' verwenden.

Die Nachrichten sind anpassbar, und verschiedene Nachrichten können für dieselbe Fehlernummer in mehreren Sprachen basierend auf einem language_id-Wert hinzugefügt werden.

Hinweis

Englische Meldungen haben die Sprach-ID 1033.

Auslösen von Fehlern mit RAISERROR

Sowohl PRINT als auch RAISERROR können verwendet werden, um Informationen oder Warnmeldungen an Anwendungen zurückzugeben. RAISERROR ermöglicht Anwendungen das Auslösen eines Fehlers, der dann vom aufrufenden Prozess abgefangen werden kann.

RAISERROR

Die Möglichkeit, Fehler in T-SQL auszuheben, erleichtert die Fehlerbehandlung in der Anwendung, da sie wie jeder andere Systemfehler gesendet wird. RAISERROR wird verwendet für:

  • Hilfe bei der Problembehandlung bei T-SQL-Code
  • Überprüfen Sie die Datenwerte.
  • Gibt Nachrichten zurück, die Variablentext enthalten.

Hinweis

Die Verwendung einer PRINT-Anweisung ähnelt dem Auslösen eines Fehlers vom Schweregrad 10.

Hier ist ein Beispiel für eine benutzerdefinierte Fehlermeldung mit RAISERROR.

RAISERROR (N'%s %d', -- Message text,
    10, -- Severity,
    1, -- State,
    N'Custom error message number',
    2)

Wenn sie ausgelöst wird, wird Folgendes zurückgegeben:

Custom error message number 2

Im vorherigen Beispiel ist %d ein Platzhalter für eine Zahl und %s ein Platzhalter für eine Zeichenfolge. Darüber hinaus sollten Sie beachten, dass eine Nachrichtennummer nicht erwähnt wurde. Wenn Fehler mit Meldungszeichenfolgen mithilfe dieser Syntax ausgelöst werden, weisen sie immer die Fehlernummer 50000 auf.

Auslösen von Fehlern mit THROW

Die THROW-Anweisung bietet eine einfachere Methode zum Auslösen von Fehlern im Code. Fehler müssen eine Fehlernummer von mindestens 50000 aufweisen.

THROW

THROW unterscheidet sich von RAISERROR auf verschiedene Arten:

  • Von THROW ausgelöste Fehler sind immer Schweregrad 16.
  • Die von THROW zurückgegebenen Nachrichten beziehen sich nicht auf Einträge in sys.sysmessages.
  • Fehler, die von THROW ausgelöst werden, verursachen nur einen Vorgangsabbruch, wenn sie in Verbindung mit SET XACT_ABORT EIN verwendet werden und die Sitzung beendet wird.
THROW 50001, 'An Error Occured',0

Erfassen von Fehlercodes mithilfe von @@Error

Der herkömmliche Fehlerbehandlungscode in SQL Server-Anwendungen wurde mithilfe von @@ERROR erstellt. Die strukturierte Ausnahmebehandlung wurde in SQL Server 2005 eingeführt und bietet eine starke Alternative zur Verwendung von @@ERROR. Es wird in der nächsten Lektion erörtert. Ein großer Teil des vorhandenen SQL Server-Fehlerbehandlungscodes basiert auf @@ERROR, daher ist es wichtig zu verstehen, wie sie damit arbeiten.

@@ERROR

@@ERROR ist eine Systemvariable, die die Fehlernummer des letzten aufgetretenen Fehlers enthält. Eine erhebliche Herausforderung bei @@ERROR besteht darin, dass der darin enthaltene Wert schnell zurückgesetzt wird, wenn jede zusätzliche Anweisung ausgeführt wird.

Betrachten Sie z. B. den folgenden Code:

RAISERROR(N'Message', 16, 1);
IF @@ERROR <> 0
PRINT 'Error=' + CAST(@@ERROR AS VARCHAR(8));
GO

Möglicherweise erwarten Sie, dass beim Ausführen des Codes die Fehlernummer in einer gedruckten Zeichenfolge zurückgegeben würde. Wenn der Code jedoch ausgeführt wird, wird Folgendes zurückgegeben:

Msg 50000, Level 16, State 1, Line 1
Message
Error=0

Der Fehler wurde ausgelöst, aber die gedruckte Nachricht lautete "Error=0". In der ersten Zeile der Ausgabe können Sie sehen, dass der Fehler wie erwartet 50000 war, wobei eine Nachricht an RAISERROR übergeben wurde. Dies liegt daran, dass die IF-Anweisung, die auf die RAISERROR-Anweisung folgt, erfolgreich ausgeführt wurde und dazu führte, dass der @@ERROR Wert zurückgesetzt wurde. Aus diesem Grund ist es wichtig, beim Arbeiten mit @@ERROR die Fehlernummer in einer Variablen zu erfassen, sobald sie ausgelöst wird, und dann die Verarbeitung mit der Variablen fortsetzen.

Sehen Sie sich den folgenden Code an, der dies veranschaulicht:

DECLARE @ErrorValue int;
RAISERROR(N'Message', 16, 1);
SET @ErrorValue = @@ERROR;
IF @ErrorValue <> 0
PRINT 'Error=' + CAST(@ErrorValue AS VARCHAR(8));

Wenn dieser Code ausgeführt wird, gibt er die folgende Ausgabe zurück:

Msg 50000, Level 16, State 1, Line 2
Message
Error=50000

Die Fehlernummer wird jetzt korrekt gemeldet.

Zentrale Fehlerbehandlung

Ein weiteres wichtiges Problem bei der Verwendung von @@ERROR für die Fehlerbehandlung besteht darin, dass es schwierig ist, in Ihrem T-SQL-Code zu zentralisieren. Die Fehlerbehandlung verteilt sich meist auf den gesamten Code. Es wäre möglich, die Fehlerbehandlung mithilfe von @@ERROR teilweise mithilfe von Bezeichnungen und GOTO-Anweisungen zu zentralisieren. Dies würde jedoch von den meisten Entwicklern heute als schlechte Programmiertechnik missbilligt werden.

Erstellen von Fehlerwarnungen

Bei bestimmten Kategorien von Fehlern können Administratoren SQL Server-Warnungen erstellen, da sie benachrichtigt werden möchten, sobald diese auftreten. Dies kann sogar auf benutzerdefinierte Fehlermeldungen angewendet werden. Sie können z. B. eine Warnung auslösen, wenn ein Transaktionsprotokoll ausgefüllt wird. Warnungen werden häufig verwendet, um Fehler mit hohem Schweregrad (z. B. Schweregrad 19 oder höher) auf administratoren aufmerksam zu machen.

Auslösen von Warnungen

Benachrichtigungen können für bestimmte Fehlermeldungen erstellt werden. Der Warnungsdienst funktioniert, indem er sich selbst als Rückrufdienst beim Ereignisprotokollierungsdienst registriert. Dies bedeutet, dass Warnungen nur bei protokollierten Fehlern funktionieren.

Es gibt zwei Möglichkeiten, eine Fehlermeldung auszuheben. Sie können die WITH LOG-Option zum Auslösen des Fehlers verwenden, oder die Nachricht kann geändert werden, um sie zu protokollieren, indem Sie sp_altermessage ausführen. Die Option WITH LOG wirkt sich nur auf die aktuelle Anweisung aus. Die Verwendung von sp_altermessage ändert das Fehlerverhalten für alle zukünftigen Verwendungen. Das Ändern von Systemfehlern über sp_altermessage ist nur ab SQL Server 2005 SP3 oder SQL Server 2008 SP1 möglich.