RAISERROR (Transact-SQL)

适用于:SQL Server Azure SQL 数据库 Azure SQL 托管实例 Azure Synapse Analytics Analytics Platform System (PDW) Microsoft Fabric 中的 SQL 终结点 Microsoft Fabric 中的仓库 Microsoft Fabric SQL 数据库

注意

声明 RAISERROR 不尊重 SET XACT_ABORT。 新应用程序应使用 THROW 而不是 RAISERROR

生成错误消息并启动会话的错误处理。 RAISERROR 可以引用 sys.messages 目录视图中存储的用户定义消息,也可以动态构建消息。 该消息作为服务器错误消息返回到调用应用程序,或返回到 TRY...CATCH 构造的关联 CATCH 块。 新应用程序应改用 THROW

Transact-SQL 语法约定

语法

适用于 SQL Server、Azure SQL 数据库和 Azure SQL 托管实例的语法:

RAISERROR ( { msg_id | msg_str | @local_variable }
    { , severity , state }
    [ , argument [ , ...n ] ] )
    [ WITH option [ , ...n ] ]

Azure Synapse Analytics 和并行数据仓库的语法:

RAISERROR ( { msg_str | @local_variable }
    { , severity , state }
    [ , argument [ , ...n ] ] )
    [ WITH option [ , ...n ] ]

参数

msg_id

使用 sp_addmessagesys.messages 目录视图中存储的用户定义的错误消息号。 用户定义的错误消息的错误号应大于 50000如果未指定msg_idRAISERROR则引发一条错误消息,并显示错误号50000

msg_str

用户定义消息,格式与 C 标准库中的 printf 函数类似。 该错误消息最长可以有 2,047 个字符。 如果消息包含 2,048 个或多个字符,则仅显示前 2,044 个字符;添加了省略号以指示消息被截断。 由于内部存储行为,替换参数使用比输出显示的字符多。 例如,具有分配值的2替换参数%d实际上在消息字符串中生成一个字符,但在内部还占用了三个额外的存储字符。 此存储要求减少了可用于消息输出的字符数。

指定msg_strRAISERROR引发一条错误消息,并显示错误号50000

msg_str 是一个字符串,具有可选的嵌入转换规格。 每个转换规格都会定义参数列表中的值如何格式化并将其置于 msg_str 中转换规格位置上的字段中。 转换规格的格式如下:

% [[flag] [width] [. precision] [{h | l}]] type

可在 msg_str 中使用的参数包括:

flag

用于确定被替换值的间距和对齐的代码。

代码 前缀或对齐 说明
- (减) 左对齐 在给定字段宽度内左对齐参数值。
+ (加) 符号前缀 如果值为有符号类型,则为带加号(+)或减号(-)的参数值前面。
0 (零) 零填充 在达到最小宽度之前在输出前面加上零。 出现减号(-)时00将忽略。
# (数字) 0x 十六进制类型的 x 前缀或 X 与数字x符号(或X格式)一起使用o时,数字符号(#)标记前面将分别包含,0x0X分别包含0任何非零值。 当、iu以数字符号 (#) 标志为前面时d,将忽略该标志。
' ' (空白) 空格填充 如果输出值有符号且为正,则在该值前加空格。 当加号 (+) 标志包含时,将忽略此填充。

width

定义放置参数值的字段的最小宽度的整数。 如果参数值的长度等于或大于 width,则打印该值,无需进行填充。 如果该值小于 width,则将该值填充到 width 中指定的长度。

星号 (*) 表示宽度是由参数列表中的关联参数指定的,该参数必须是整数值。

精度

从字符串值的参数值中得到的最大字符数。 例如,如果一个字符串具有五个字符并且精度为 3,则只使用字符串值的前三个字符。

对于整数值,precision 是指打印的最小位数。

星号 (*) 表示精度是由参数列表中的关联参数指定的,该参数必须是整数值。

{h | l} type

与字符类型d、、、osx、或Xu和创建 shortint (h) 或 longintl) 值一i起使用。

类型规范 表示
di 带符号的整数
o 无符号的八进制数
s 字符串
u 无符号的整数
xX 无符号的十六进制数

这些类型规范基于最初为 C 标准库中 printf 函数定义的规范。 RAISERROR 消息字符串中使用的类型规范映射到 Transact-SQL 数据类型,而 printf 中使用的规范映射到 C 语言数据类型。 当 Transact-SQL 没有类似于关联的 C 数据类型的数据类型时,不支持在类型规范中使用printfRAISERROR。 例如, %p 由于 Transact-SQL 没有指针数据类型,因此不支持 RAISERROR 指针规范。

若要将值转换为 Transact-SQL bigint 数据类型,请指定 %I64d

@local_variable

包含格式与msg_str相同的字符串的任何有效字符数据类型的变量。 @local_variable 必须为 char 或 varchar,或者能够隐式转换为这些数据类型。

severity

与此消息关联的用户定义的严重性级别。 使用 msg_id 引发使用 sp_addmessage 创建的用户定义消息时,RAISERROR 上指定的严重性会替代 sp_addmessage 中指定的严重性。

对于从 19 到 25 的严重性级别,需要 WITH LOG 此选项。 小于 0 解释为 0严重性级别。 将大于 25 的严重级别解释为 25。

注意

20 到 25 之间的严重级别被认为是致命的。 如果遇到致命的严重级别,客户端连接将在收到消息后终止,并将错误记录到错误日志和应用程序日志。

可以指定 -1 返回与错误关联的严重性值,如以下示例所示。

RAISERROR (15600, -1, -1, 'mysp_CreateCustomer');

结果集如下。

Msg 15600, Level 15, State 1, Line 1
An invalid parameter or option was specified for procedure 'mysp_CreateCustomer'.

State

0 到 255 之间的整数。 负值默认为 1。 不应使用大于 255 的值。

如果在多个位置引发相同的用户定义错误,则针对每个位置使用唯一的状态号有助于找到引发错误的代码段。

argument

用于代替 msg_str 或对应于 msg_id 的消息中定义的变量的参数。 可以有零个或多个替换参数,但替换参数总数不能超过 20。 每个替换参数可以是本地变量或下列任何数据类型:tinyint、smallint、int、char、varchar、nchar、nvarchar、binary 或 varbinary。 不支持其他数据类型。

option

错误的自定义选项,可以是下表中的任一值。

说明
LOG 记录错误日志中的错误,以及 SQL Server 数据库引擎实例的应用程序日志。 记录到错误日志的错误目前被限定为最多 440 字节。 只有 sysadmin 固定服务器角色的成员或具有ALTER TRACE权限的用户才能指定 WITH LOG

适用范围:SQL Server
NOWAIT 将消息立即发送给客户端。

适用于:SQL Server、Aure SQL 数据库和 Azure SQL 托管实例
SETERROR @@ERROR 值和 ERROR_NUMBER 值设置为 msg_id 或 50000,不用考虑严重级别。

适用于:SQL Server、Aure SQL 数据库和 Azure SQL 托管实例

注解

RAISERROR 生成的错误与数据库引擎代码生成的错误的运行方式相同。 RAISERROR 指定的值由 ERROR_LINEERROR_MESSAGEERROR_NUMBERERROR_PROCEDUREERROR_SEVERITYERROR_STATE@@ERROR 系统函数报告。 当 RAISERROR 在块中 TRY 严重性为 11 或更高版本时,它会将控制权传输到关联的 CATCH 块。 如果 RAISERROR 在下列情况下运行,便会将错误返回到调用方:

  • 在任何 TRY 块的作用域之外运行。
  • 在严重级别为 10 或更低的情况下在 TRY 块中运行。
  • 在严重级别为 20 或更高的情况下终止数据库连接。

CATCH 块可以使用 RAISERROR 来再次引发调用 CATCH 块的错误,方法是使用 ERROR_NUMBERERROR_MESSAGE 之类的系统函数检索原始错误信息。 @@ERROR0对于严重性为 1 到 10 的消息,默认设置为 。

当msg_id指定目录视图中可用的sys.messages用户定义消息时RAISERROR使用与应用于使用msg_str指定的用户定义的消息的文本相同的规则处理来自文本列的消息。 用户定义的消息文本可以包含转换规范,并将 RAISERROR 参数值映射到转换规范中。 使用 sp_addmessage 添加用户定义错误消息,使用 sp_dropmessage 删除用户定义错误消息。

RAISERROR 可用作将消息返回到调用应用程序的替代方法 PRINTRAISERROR 支持与 C 标准库中函数的功能 printf 类似的字符替换,而 Transact-SQL PRINT 语句则不支持。 该 PRINT 语句不受块的影响 TRY ,而 RAISERROR TRY 块中严重性为 11 到 19 的运行将控制权传输到关联的 CATCH 块。 指定严重级别为 10 或更低以使用 RAISERROR 返回 TRY 块中的消息,而不必调用 CATCH 块。

通常,连续的参数替换连续的转换规格;第一个参数替换第一个转换规格,第二个参数替换第二个转换规格,以此类推。 例如,在以下 RAISERROR 语句中,第一个参数 N'number' 替换第一个转换规格 %s,第二个参数 5 替换第二个转换规格 %d.

RAISERROR (N'This is message %s %d.', -- Message text.
    10, -- Severity,
    1, -- State,
    N'number', -- First argument.
    5); -- Second argument.
-- The message text returned is: This is message number 5.
GO

如果为转换规格的宽度或精度指定了星号 (*),则要用于宽度或精度的值被指定为整数参数值。 在这种情况下,一个转换规格最多可以使用三个参数,分别用作宽度、精度和代替值。

例如,下列两个 RAISERROR 语句都返回相同的字符串。 一个指定参数列表中的宽度值和精度值;另一个指定转换规格中的宽度值和精度值。

RAISERROR (N'<\<%*.*s>>', -- Message text.
    10, -- Severity,
    1, -- State,
    7, -- First argument used for width.
    3, -- Second argument used for precision.
    N'abcde'); -- Third argument supplies the string.
-- The message text returned is: <<    abc>>.
GO
RAISERROR (N'<\<%7.3s>>', -- Message text.
    10, -- Severity,
    1, -- State,
    N'abcde'); -- First argument supplies the string.
-- The message text returned is: <<    abc>>.
GO

权限

任何用户可以指定从 0 到 18 的严重性级别。 严重级别从 19 到 25 只能由 sysadmin 固定服务器角色的成员或具有ALTER TRACE权限的用户指定。

示例

A. 从 CATCH 块返回错误信息

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

注意

RAISERROR 仅能生成状态为 1 到 127 的错误。 由于数据库引擎可能会引发状态为 0 的错误,因此建议在将错误状态作为值传递给状态参数RAISERROR之前检查ERROR_STATE返回的错误状态。

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;

B. 在 sys.messages 中创建即席消息

以下示例演示如何引发存储在 sys.messages 目录视图中的消息。 该消息已 sys.messages 添加到目录视图中, sp_addmessage 方法是使用系统存储过程作为消息编号 50005

EXEC sp_addmessage @msgnum = 50005,
    @severity = 10,
    @msgtext = N'<\<%7.3s>>';
GO
RAISERROR (50005, -- Message ID.
    10, -- Severity,
    1, -- State,
    N'abcde'); -- First argument supplies the string.
-- The message text returned is: <<    abc>>.
GO
EXEC sp_dropmessage @msgnum = 50005;
GO

°C 使用局部变量提供消息文本

以下代码示例显示如何使用局部变量为 RAISERROR 语句提供消息文本。

DECLARE @StringVariable NVARCHAR(50);
SET @StringVariable = N'<\<%7.3s>>';

RAISERROR (@StringVariable, -- Message text.
    10, -- Severity,
    1, -- State,
    N'abcde'); -- First argument supplies the string.
-- The message text returned is: <<    abc>>.
GO