kry*_*tah 7 sql-server t-sql sql-server-2012
我正在经历一些THROW
我无法理解的行为。考虑以下存储过程:
CREATE PROCEDURE usp_division_err AS
SET NOCOUNT ON;
BEGIN TRY
EXEC('select 1/0')
END TRY
BEGIN CATCH
THROW;
END CATCH
Run Code Online (Sandbox Code Playgroud)
执行该过程时,会引发以下错误:
消息 8134,级别 16,状态 1,第 1 行
遇到除以零错误。
请注意,没有包含有关在哪个过程中引发错误的信息。那是因为错误的动态 SQL 在另一个作用域中执行,这很好。但是,将CATCH
-block更改为如下所示
BEGIN CATCH
THROW 50000, 'An error occurred.', 1;
END CATCH
Run Code Online (Sandbox Code Playgroud)
并且该过程的执行将引发此错误:
Msg 50000, Level 16, State 1, Procedure usp_division_err, Line 7 [Batch Start Line 0]
发生错误。
执行动态SQL时仍然遇到错误,但是当我手动指定错误号和错误消息( 的第一个和第二个参数THROW
)时,不知何故出现了执行过程的procedure-name。
为什么过程名称出现在第二个错误消息中而不是第一个错误消息中?
代码CATCH
如下:
BEGIN CATCH
DECLARE @msg nvarchar(4000) = ERROR_MESSAGE()
DECLARE @errno int = 50000 + ERROR_NUMBER();
DECLARE @state int = ERROR_STATE();
THROW @errno, @msg, @state;
END CATCH
Run Code Online (Sandbox Code Playgroud)
这允许您将所有参数传递到THROW
语句中,以便它可以将它们发送回调用者。
我这样测试过:
USE tempdb;
IF OBJECT_ID('dbo.usp_division_err', 'P') IS NOT NULL
DROP PROCEDURE dbo.usp_division_err;
GO
CREATE PROCEDURE dbo.usp_division_err AS
SET NOCOUNT ON;
BEGIN TRY
EXEC('select 1/0');
END TRY
BEGIN CATCH
DECLARE @msg nvarchar(4000) = ERROR_MESSAGE()
DECLARE @errno int = 50000 + ERROR_NUMBER();
DECLARE @state int = ERROR_STATE();
THROW @errno, @msg, @state;
END CATCH
GO
EXEC dbo.usp_division_err;
Run Code Online (Sandbox Code Playgroud)
结果:
消息 58134,级别 16,状态 1,过程 dbo.usp_division_err,第 10 行 [批处理开始第 16 行]
遇到除以零错误。
要获得本机错误编号,您只需从报告的错误编号中减去 50000。由于 的参数THROW
是可选的,因此 内部必须有两个代码路径THROW
,一个报告过程名称,另一个则不报告。我将让读者决定哪个代码路径可以做到这一点。
归档时间: |
|
查看次数: |
772 次 |
最近记录: |