THROW (Transact-SQL)

引发异常,并将执行转移到 SQL Server 2014 中 TRY…CATCH 构造的 CATCH 块。

主题链接图标 Transact-SQL 语法约定

适用范围:SQL Server(SQL Server 2012 至当前版本),Windows Azure SQL Database(初始版本至当前版本)。

语法

THROW [ { error_number | @local_variable },
        { message | @local_variable },
        { state | @local_variable } ] 
[ ; ]

参数

  • error_number
    表示异常的常量或变量。 error_number 的数据类型为 int,并且必须大于或等于 50000 且小于或等于 2147483647。

  • message
    描述异常的字符串或变量。 message 的数据类型为 nvarchar(2048)。

  • state
    在 0 到 255 之间的常量或变量,指示与消息关联的状态。 state 的数据类型为 tinyint。

注释

THROW 语句前的语句必须后跟分号 (;) 语句终止符。

如果 TRY…CATCH 构造不可用,则会话结束。 设置引发异常的行号和过程。 将严重性设置为 16。

如果指定 THROW 语句时未使用任何参数,该语句必须出现在 CATCH 块内。 这将导致引发已捕获异常。 THROW 语句中出现任何错误都将导致语句批处理结束。

RAISERROR 与 THROW 之间的差异

下表列出了 RAISERROR 和 THROW 语句之间的一些差异。

RAISERROR 语句

THROW 语句

如果将 msg_id 传递给 RAISERROR,则必须在 sys.messages 中定义 ID。

不必在 sys.messages 中定义 error_number 参数。

msg_str 参数可以包含 printf 格式样式。

message 参数不接受 printf 样式的格式设置。

severity 参数指定异常的严重性。

没有 severity 参数。 始终将异常严重性设置为 16。

示例

A.使用 THROW 引发异常

以下示例演示如何使用 THROW 语句引发异常。

THROW 51000, 'The record does not exist.', 1;

下面是结果集:

Msg 51000, Level 16, State 1, Line 1

The record does not exist.

B.使用 THROW 再次引发异常

以下示例演示如何使用 THROW 语句再次引发上次引发的异常。

USE tempdb;
GO
CREATE TABLE dbo.TestRethrow
(    ID INT PRIMARY KEY
);
BEGIN TRY
    INSERT dbo.TestRethrow(ID) VALUES(1);
--  Force error 2627, Violation of PRIMARY KEY constraint to be raised.
    INSERT dbo.TestRethrow(ID) VALUES(1);
END TRY
BEGIN CATCH

    PRINT 'In catch block.';
    THROW;
END CATCH;

下面是结果集:

PRINT 'In catch block.';

Msg 2627, Level 14, State 1, Line 1

Violation of PRIMARY KEY constraint 'PK__TestReth__3214EC272E3BD7D3'. Cannot insert duplicate key in object 'dbo.TestRethrow'.

The statement has been terminated.

C.使用带 THROW 的 FORMATMESSAGE

下面的示例说明如何使用带 THROW 的 FORMATMESSAGE 函数来引发自定义错误消息。 该示例首先使用 sp_addmessage 创建用户定义的错误消息。 因为 THROW 语句不允许像 RAISERROR 那样替换 message 参数中的参数,因此使用 FORMATMESSAGE 函数传递错误消息 60000 所要求的三个参数值。

EXEC sys.sp_addmessage
     @msgnum   = 60000
,@severity = 16
,@msgtext  = N'This is a test message with one numeric parameter (%d), one string parameter (%s), and another string parameter (%s).'
    ,@lang = 'us_english'; 
GO

DECLARE @msg NVARCHAR(2048) = FORMATMESSAGE(60000, 500, N'First string', N'second string'); 

THROW 60000, @msg, 1; 

下面是结果集:

Msg 60000, Level 16, State 1, Line 2

This is a test message with one numeric parameter (500), one string parameter (First string), and another string parameter (second string).

请参阅

参考

FORMATMESSAGE (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)

RAISERROR (Transact-SQL)

@@ERROR (Transact-SQL)

GOTO (Transact-SQL)

BEGIN...END (Transact-SQL)

XACT_STATE (Transact-SQL)

SET XACT_ABORT (Transact-SQL)

概念

数据库引擎错误严重性