使用 RAISERROR

RAISERROR 用于将与 SQL Server 数据库引擎生成的系统错误或警告消息使用相同格式的消息返回到应用程序中。

RAISERROR 还可以返回:

  • 已通过 sp_addmessage 系统存储过程创建的用户定义的错误消息。这些消息的消息号大于 50000;可在 sys.messages 目录视图中查看这些消息。

  • 在 RAISERROR 语句中指定的消息字符串。

RAISERROR 还可以:

  • 分配特定的错误号、严重度和状态。

  • 请求将错误记录到数据库引擎错误日志和 Microsoft Windows 应用程序日志中。

  • 将参数值代入消息正文中,这与 C 语言中的 printf_s 函数非常相似。

RAISERROR 和 PRINT 都可以用来将信息性消息或警告消息返回到某个应用程序中。RAISERROR 返回的消息正文可以使用类似 C 标准库中的 printf_s 函数的字符串替换功能来生成,然而 PRINT 只能返回字符串或字符表达式。如果在 TRY...CATCH 构造的 TRY 块中执行的 RAISERROR 严重度介于 11 到 19 之间,会导致将控制传递到关联的 CATCH 块。如果指定 10 或更低的严重度,将使用 RAISERROR 返回消息,而不调用 CATCH 块。PRINT 不会将控制传输到 CATCH 块。

当 RAISERROR 在 sys.messages 中与用户定义消息的 msg_id 一起使用时,msg_id 作为 SQL Server 错误号或本机错误代码返回。而当 RAISERROR 用于 msg_str 而不是 msg_id 时,则返回的 SQL Server 错误号和本机错误号为 50000。

当使用 RAISERROR 返回用户定义的错误消息时,请在每个引用该错误的 RAISERROR 中使用不同的状态号码。这可以在发生错误时帮助进行错误诊断。

使用 RAISERROR 可以:

  • 帮助对 Transact-SQL 代码进行故障排除。

  • 检查数据值。

  • 返回包含变量文本的消息。

  • 导致执行从 TRY 块跳到关联的 CATCH 块。

  • 将错误信息从 CATCH 块返回到进行调用的批处理或应用程序。

以下示例将替换返回到应用程序的消息中的 DB_ID() 和 DB_NAME() 函数的值:

DECLARE @DBID INT;
SET @DBID = DB_ID();

DECLARE @DBNAME NVARCHAR(128);
SET @DBNAME = DB_NAME();

RAISERROR
    (N'The current database ID is:%d, the database name is: %s.',
    10, -- Severity.
    1, -- State.
    @DBID, -- First substitution argument.
    @DBNAME); -- Second substitution argument.
GO

以下示例使用用户定义的消息提供了同样的信息:

EXECUTE sp_dropmessage 50005;
GO
EXECUTE sp_addmessage 50005, -- Message id number.
    10, -- Severity.
    N'The current database ID is: %d, the database name is: %s.';
GO
DECLARE @DBID INT;
SET @DBID = DB_ID();

DECLARE @DBNAME NVARCHAR(128);
SET @DBNAME = DB_NAME();

RAISERROR (50005,
    10, -- Severity.
    1, -- State.
    @DBID, -- First substitution argument.
    @DBNAME); -- Second substitution argument.
GO

以下代码示例显示如何在 TRY 块中使用 RAISERROR 使执行跳至关联的 CATCH 块中。它还显示了如何使用 RAISERROR 返回有关调用 CATCH 块的错误的信息。

注意注意

RAISERROR 只能生成状态为 1 到 127 的错误。由于数据库引擎可能引发状态为 0 的错误,因此,建议您先检查由 ERROR_STATE 返回的错误状态,然后将它作为一个值传递给状态参数 RAISERROR。

BEGIN TRY
    -- RAISERROR with severity 11-19 will cause execution to 
    -- jump to the CATCH block
    RAISERROR ('Error raised in TRY block.', -- Message text.
               16, -- Severity.
               1 -- State.
               );
END TRY
BEGIN CATCH
    DECLARE @ErrorMessage NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;

    SELECT @ErrorMessage = ERROR_MESSAGE(),
           @ErrorSeverity = ERROR_SEVERITY(),
           @ErrorState = ERROR_STATE();

    -- Use RAISERROR inside the CATCH block to return 
    -- error information about the original error that 
    -- caused execution to jump to the CATCH block.
    RAISERROR (@ErrorMessage, -- Message text.
               @ErrorSeverity, -- Severity.
               @ErrorState -- State.
               );
END CATCH;