在 Transact-SQL 中检索错误信息
在 Transact-SQL 中有两种方式可以获取错误信息:
- 在 TRY...CATCH 构造的 CATCH 块的作用域内,您可以使用以下系统函数:
- ERROR_LINE(),返回出现错误的行号。
- ERROR_MESSAGE(),返回将返回给应用程序的消息文本。该文本包括为所有可替换参数提供的值,如长度、对象名或时间。
- ERROR_NUMBER() 返回错误号。
- ERROR_PROCEDURE(),返回出现错误的存储过程或触发器的名称。如果在存储过程或触发器中未出现错误,该函数返回 NULL。
- ERROR_SEVERITY() 返回严重性。
- ERROR_STATE(),返回状态。
- 在执行任何 Transact-SQL 语句之后,您可以立即使用 @@ERROR 函数测试错误并检索错误号。
使用 ERROR_LINE、ERROR_MESSAGE、ERROR_NUMBER、ERROR_PROCEDURE、ERROR_SEVERITY 和 ERROR_STATE
当用于 TRY...CATCH 构造的 CATCH 块的作用域内时,ERROR_LINE、ERROR_MESSAGE、ERROR_NUMBER、ERROR_PROCEDURE、ERROR_SEVERITY 和 ERROR_STATE 函数仅返回错误信息。用于 CATCH 块的作用域外时,它们会返回 NULL。这些函数返回有关导致 CATCH 块被调用的错误的信息。只要是在 CATCH 块的作用域内运行,这些函数即使被引用多次也将返回相同的错误信息。这些函数为 Transact-SQL 语句提供了与返回给应用程序的数据相同的数据。
在嵌套的 CATCH 块中,ERROR_LINE、ERROR_MESSAGE、ERROR_NUMBER、ERROR_PROCEDURE、ERROR_SEVERITY 和 ERROR_STATE 函数返回的错误信息特定于它们在其中被引用的 CATCH 块。例如,外部 TRY...CATCH 构造的 CATCH 块可能具有嵌套 TRY...CATCH 构造。在嵌套的 CATCH 块内,这些函数将返回有关调用内部 CATCH 块的错误的信息。在外部 CATCH 块,这些函数将返回有关调用 CATCH 块的错误的信息。
以下示例通过显示在外部 CATCH 块引用 ERROR_MESSAGE 时,函数返回外部 TRY 块生成的消息文本,说明了此种情况。当在内部 CATCH 块中引用 ERROR_MESSAGE 时,它返回在内部 TRY 块中生成的文本。此示例还说明了在外部 CATCH 块中 ERROR_MESSAGE 始终返回在外部 TRY 块中生成的消息,即使在运行内部 TRY...CATCH 构造后。
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
使用 @@ERROR 检索信息
@@ERROR 函数可用于捕获上一 Transact-SQL 语句生成的错误号。@@ERROR 仅在生成错误的 Transact-SQL 语句之后,立即返回错误信息。
- 如果生成错误的语句在 TRY 块中,则 @@ERROR 值必须在相关的 CATCH 块的第一条语句中进行测试和检索。
- 如果生成错误的语句不在 TRY 块中,则 @@ERROR 值必须在生成错误的语句之后立即在语句中进行测试和检索。
在 CATCH 块的作用域外,@@ERROR 中的错误号是有关 Transact-SQL 代码内错误的唯一可用信息。如果错误使用了 sys.messages 中定义的错误消息,您可以按照本例中所介绍的那样,检索定义的严重性和 sys.messages 中的错误消息文本。
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
请参阅
概念
在 Transact-SQL 中使用 TRY...CATCH
使用 RAISERROR
使用 @@ERROR
其他资源
了解数据库引擎错误
sys.messages (Transact-SQL)
TRY...CATCH (Transact-SQL)
ERROR_LINE (Transact-SQL)
ERROR_MESSAGE (Transact-SQL)
ERROR_NUMBER (Transact-SQL)
ERROR_PROCEDURE (Transact-SQL)
ERROR_SEVERITY (Transact-SQL)
ERROR_STATE (Transact-SQL)