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。
语法
适用于 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_addmessage
在 sys.messages
目录视图中存储的用户定义的错误消息号。 用户定义的错误消息的错误号应大于 50000
。 如果未指定msg_id,RAISERROR
则引发一条错误消息,并显示错误号50000
。
msg_str
用户定义消息,格式与 C 标准库中的 printf
函数类似。 该错误消息最长可以有 2,047 个字符。 如果消息包含 2,048 个或多个字符,则仅显示前 2,044 个字符;添加了省略号以指示消息被截断。 由于内部存储行为,替换参数使用比输出显示的字符多。 例如,具有分配值的2
替换参数%d
实际上在消息字符串中生成一个字符,但在内部还占用了三个额外的存储字符。 此存储要求减少了可用于消息输出的字符数。
指定msg_str时,RAISERROR
引发一条错误消息,并显示错误号50000
。
msg_str 是一个字符串,具有可选的嵌入转换规格。 每个转换规格都会定义参数列表中的值如何格式化并将其置于 msg_str 中转换规格位置上的字段中。 转换规格的格式如下:
% [[flag] [width] [. precision] [{h | l}]] type
可在 msg_str 中使用的参数包括:
flag
用于确定被替换值的间距和对齐的代码。
代码 | 前缀或对齐 | 说明 |
---|---|---|
- (减) |
左对齐 | 在给定字段宽度内左对齐参数值。 |
+ (加) |
符号前缀 | 如果值为有符号类型,则为带加号(+ )或减号(- )的参数值前面。 |
0 (零) |
零填充 | 在达到最小宽度之前在输出前面加上零。 出现减号(- )时0 ,0 将忽略。 |
# (数字) |
0x 十六进制类型的 x 前缀或 X |
与数字x 符号(或X 格式)一起使用o 时,数字符号(# )标记前面将分别包含,0x 或0X 分别包含0 任何非零值。 当、i 或u 以数字符号 (# ) 标志为前面时d ,将忽略该标志。 |
' ' (空白) |
空格填充 | 如果输出值有符号且为正,则在该值前加空格。 当加号 (+ ) 标志包含时,将忽略此填充。 |
width
定义放置参数值的字段的最小宽度的整数。 如果参数值的长度等于或大于 width,则打印该值,无需进行填充。 如果该值小于 width,则将该值填充到 width 中指定的长度。
星号 (*
) 表示宽度是由参数列表中的关联参数指定的,该参数必须是整数值。
精度
从字符串值的参数值中得到的最大字符数。 例如,如果一个字符串具有五个字符并且精度为 3,则只使用字符串值的前三个字符。
对于整数值,precision 是指打印的最小位数。
星号 (*
) 表示精度是由参数列表中的关联参数指定的,该参数必须是整数值。
{h | l} type
与字符类型d
、、、o
、s
x
、或X
u
和创建 shortint (h
) 或 longint (l
) 值一i
起使用。
类型规范 | 表示 |
---|---|
d 或 i |
带符号的整数 |
o |
无符号的八进制数 |
s |
字符串 |
u |
无符号的整数 |
x 或 X |
无符号的十六进制数 |
这些类型规范基于最初为 C 标准库中 printf
函数定义的规范。 RAISERROR
消息字符串中使用的类型规范映射到 Transact-SQL 数据类型,而 printf
中使用的规范映射到 C 语言数据类型。 当 Transact-SQL 没有类似于关联的 C 数据类型的数据类型时,不支持在类型规范中使用printf
RAISERROR
。 例如, %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_LINE
、ERROR_MESSAGE
、ERROR_NUMBER
、ERROR_PROCEDURE
、ERROR_SEVERITY
、ERROR_STATE
和 @@ERROR
系统函数报告。 当 RAISERROR
在块中 TRY
严重性为 11 或更高版本时,它会将控制权传输到关联的 CATCH
块。 如果 RAISERROR
在下列情况下运行,便会将错误返回到调用方:
- 在任何
TRY
块的作用域之外运行。 - 在严重级别为 10 或更低的情况下在
TRY
块中运行。 - 在严重级别为 20 或更高的情况下终止数据库连接。
CATCH
块可以使用 RAISERROR
来再次引发调用 CATCH
块的错误,方法是使用 ERROR_NUMBER
和 ERROR_MESSAGE
之类的系统函数检索原始错误信息。 @@ERROR
0
对于严重性为 1 到 10 的消息,默认设置为 。
当msg_id指定目录视图中可用的sys.messages
用户定义消息时,RAISERROR
使用与应用于使用msg_str指定的用户定义的消息的文本相同的规则处理来自文本列的消息。 用户定义的消息文本可以包含转换规范,并将 RAISERROR
参数值映射到转换规范中。 使用 sp_addmessage
添加用户定义错误消息,使用 sp_dropmessage
删除用户定义错误消息。
RAISERROR
可用作将消息返回到调用应用程序的替代方法 PRINT
。 RAISERROR
支持与 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
相关内容
- SQL 数据库函数有哪些?
- DECLARE @local_variable (Transact-SQL)
- PRINT (Transact-SQL)
- sp_addmessage (Transact-SQL)
- sp_dropmessage (Transact-SQL)
- sys.messages (Transact-SQL)
- xp_logevent (Transact-SQL)
- @@ERROR (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)
- TRY...CATCH (Transact-SQL)