Abrufen von Fehlerinformationen in Transact-SQL
Fehlerinformationen können in Transact-SQL auf zweierlei Art abgerufen werden:
Innerhalb des Bereichs des CATCH-Blockes eines TRY…CATCH-Konstrukts können Sie folgende Systemfunktionen verwenden:
ERROR_LINE() gibt die Zeilennummer zurück, in der der Fehler aufgetreten ist.
ERROR_MESSAGE() gibt den Text der Meldung zurück, die an die Anwendung zurückgegeben werden würde. Der Text schließt die Werte ein, die für beliebige ersetzbare Parameter angegeben sind, beispielsweise Längenangaben, Objektnamen oder Zeitangaben.
ERROR_NUMBER() gibt die Fehlernummer zurück.
ERROR_PROCEDURE() gibt den Namen der gespeicherten Prozedur oder des Triggers mit dem Fehler zurück. Diese Funktion gibt NULL zurück, wenn der Fehler nicht innerhalb einer gespeicherten Prozedur bzw. eines Triggers aufgetreten ist.
ERROR_SEVERITY() gibt den Schweregrad zurück.
ERROR_STATE() gibt den Status zurück.
Sofort nach dem Ausführen einer Transact-SQL-Anweisung können Sie mithilfe der @@ERROR-Funktion auf Fehler testen und ggf. die Fehlernummer abrufen.
Verwenden von ERROR_LINE, ERROR_MESSAGE, ERROR_NUMBER, ERROR_PROCEDURE, ERROR_SEVERITY und ERROR_STATE
Die Funktionen ERROR_LINE, ERROR_MESSAGE, ERROR_NUMBER, ERROR_PROCEDURE, ERROR_SEVERITY und ERROR_STATE geben nur dann Fehlerinformationen zurück, wenn sie innerhalb des Bereichs des CATCH-Blockes eines TRY…CATCH-Konstrukts verwendet werden. Außerhalb des Bereichs eines CATCH-Blockes geben Sie NULL zurück. Diese Funktionen geben Informationen zu dem Fehler zurück, durch den der CATCH-Block aufgerufen wurde. Die Funktionen geben ungeachtet der Ausführungsposition innerhalb des Bereichs eines CATCH-Blockes dieselben Fehlerinformationen zurück, auch wenn mehrfach auf sie verwiesen wird. Die Funktionen stellen für Transact-SQL-Anweisungen dieselben Daten bereit, die an die Anwendung zurückgegeben wird.
In geschachtelten CATCH-Blöcken geben die Funktionen ERROR_LINE, ERROR_MESSAGE, ERROR_NUMBER, ERROR_PROCEDURE, ERROR_SEVERITY und ERROR_STATE die Fehlerinformationen zurück, die für den CATCH-Block spezifisch sind, in dem auf sie verwiesen wird. So kann beispielsweise der CATCH-Block eines äußeren TRY...CATCH-Konstrukts ein geschachteltes TRY...CATCH-Konstrukt aufweisen. Innerhalb des geschachtelten CATCH-Blockes geben diese Funktionen Informationen zu dem Fehler zurück, der den inneren CATCH-Block aufgerufen hat. Dieselben Funktionen im äußeren CATCH-Block würden Informationen zu dem Fehler zurückgeben, der diesen CATCH-Block aufgerufen hat.
Dies wird im nachfolgenden Beispiel verdeutlicht, aus dem Folgendes hervorgeht: Wenn im äußeren CATCH-Block auf ERROR_MESSAGE verwiesen wird, wird der vom äußeren TRY-Block generierte Meldungstext zurückgegeben. Wenn der Verweis im inneren CATCH-Block erfolgt, gibt ERROR_MESSAGE den im inneren TRY-Block generierten Text zurück. Im Beispiel wird außerdem veranschaulicht, dass ERROR_MESSAGE im äußeren CATCH-Block stets die im äußeren TRY-Block generierte Meldung zurückgibt, selbst nach dem Ausführen des inneren TRY...CATCH-Konstrukts.
IF EXISTS (SELECT message_id FROM sys.messages
WHERE message_id = 50010)
EXECUTE sp_dropmessage 50010;
GO
EXECUTE sp_addmessage @msgnum = 50010,
@severity = 16,
@msgtext = N'Message text is from the %s TRY block.';
GO
BEGIN TRY -- Outer TRY block.
-- Raise an error in the outer TRY block.
RAISERROR (50010, -- Message id.
16, -- Severity,
1, -- State,
N'outer'); -- Indicate TRY block.
END TRY -- Outer TRY block.
BEGIN CATCH -- Outer CATCH block.
-- Print the error message recieved for this
-- CATCH block.
PRINT N'OUTER CATCH1: ' + ERROR_MESSAGE();
BEGIN TRY -- Inner TRY block.
-- Start a nested TRY...CATCH and generate
-- a new error.
RAISERROR (50010, -- Message id.
16, -- Severity,
2, -- State,
N'inner'); -- Indicate TRY block.
END TRY -- Inner TRY block.
BEGIN CATCH -- Inner CATCH block.
-- Print the error message recieved for this
-- CATCH block.
PRINT N'INNER CATCH: ' + ERROR_MESSAGE();
END CATCH; -- Inner CATCH block.
-- Show that ERROR_MESSAGE in the outer CATCH
-- block still returns the message from the
-- error generated in the outer TRY block.
PRINT N'OUTER CATCH2: ' + ERROR_MESSAGE();
END CATCH; -- Outer CATCH block.
GO
Abrufen von Informationen mit @@ERROR
Die @@ERROR-Funktion kann zum Aufzeichnen der Nummer eines Fehlers verwendet werden, der von der vorherigen Transact-SQL-Anweisung generiert wurde. @@ERROR gibt Fehlerinformationen nur unmittelbar nach der Transact-SQL-Anweisung zurück, die den Fehler generiert.
Wenn sich die Anweisung, die den Fehler generiert, in einem TRY-Block befindet, muss der @@ERROR in der ersten Anweisung im zugehörigen CATCH-Block getestet und abgerufen werden.
Wenn sich die Anweisung, die den Fehler generiert, nicht in einem TRY-Block befindet, muss der @@ERROR-Wert in der ersten Anweisung unmittelbar nach der getestet und abgerufen werden, die den Fehler generiert hat.
Außerhalb des Bereichs eines CATCH-Blockes ist die Fehlernummer in @@ERROR die einzige Information, die in Transact-SQL-Code hinsichtlich eines Fehlers verfügbar ist. Wenn von dem Fehler eine in sys.messages definierte Fehlermeldung verwendet wurde, können Sie den definierten Schweregrad und den Text der Fehlermeldung aus sys.messages abrufen, wie im nachfolgenden Beispiel dargestellt.
IF EXISTS (SELECT message_id FROM sys.messages
WHERE message_id = 50010)
EXECUTE sp_dropmessage 50010;
GO
-- Define a message with text that accepts
-- a substitution string.
EXECUTE sp_addmessage @msgnum = 50010,
@severity = 16,
@msgtext = N'Substitution string = %s.';
GO
DECLARE @ErrorVariable INT;
-- RAISERROR uses a different severity and
-- supplies a substitution argument.
RAISERROR (50010, -- Message id.
15, -- Severity,
1, -- State,
N'ABC'); -- Substitution Value.
-- Save @@ERROR.
SET @ErrorVariable = @@ERROR;
-- The results of this select illustrate that
-- outside a CATCH block only the original
-- information from sys.messages is available to
-- Transact-SQL statements. The actual message
-- string returned to the application is not
-- available to Transact-SQL statements outside
-- of a CATCH block.
SELECT @ErrorVariable AS ErrorID,
text
FROM sys.messages
WHERE message_id = @ErrorVariable;
GO
Siehe auch