应该指出的是,即使在技术上有可能在THROW
和之间切换RAISERROR
,您(很可能)也不想实际执行此操作。为什么?因为无参数的非常漂亮的能力THROW
,以使用重新抛出错误相同消息编号(即Msg 8134
,而不是Msg X
其中X
> = 50000)不是它们之间的唯一区别:THROW
是分批中止而RAISERROR
不是。如下所示,这可能是重要的行为差异。
测试设置
--DROP PROC ##Throw;
--DROP PROC ##RaisError;
GO
CREATE PROCEDURE ##Throw
AS
SET NOCOUNT ON;
BEGIN TRY
SELECT 1/0 AS [DivideByZero];
END TRY
BEGIN CATCH
THROW;
END CATCH;
SELECT 1 AS [AA];
GO
CREATE PROCEDURE ##RaisError
AS
SET NOCOUNT ON;
BEGIN TRY
SELECT 1/0 AS [DivideByZero];
END TRY
BEGIN CATCH
RAISERROR('test, yo!', 16, 1);
-- RETURN; -- typically at end of CATCH block when using RAISERROR
END CATCH;
SELECT 2 AS [BB];
GO
测试1
EXEC ##Throw;
SELECT 3 AS [CC];
返回值:
"Results" Tab:
DivideByZero
{empty result set}
"Messages" Tab:
Msg 8134, Level 16, State 1, Procedure ##Throw, Line 38
Divide by zero error encountered.
测试2
EXEC ##RaisError;
SELECT 4 AS [DD];
返回值:
"Results" Tab:
DivideByZero
{empty result set}
BB
2
DD
4
"Messages" Tab:
Msg 50000, Level 16, State 1, Procedure ##RaisError, Line 45
test, yo!
公平地说,可以通过以下操作掩盖这种差异:
- 始终
THROW
在TRY...CATCH
构造中使用以下代码包装所有对代码的调用:
- 切勿将代码放在
THROW
(井号除外END CATCH;
)之后
测试3
BEGIN TRY
EXEC ##Throw;
SELECT 5 AS [EE];
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS [ErrorNumber], ERROR_MESSAGE() AS [ErrorMessage];
END CATCH;
SELECT 6 AS [FF];
GO
返回值:
"Results" Tab:
DivideByZero
{empty result set}
ErrorNumber ErrorMessage
8134 Divide by zero error encountered.
FF
6
测试4
BEGIN TRY
EXEC ##RaisError;
SELECT 7 AS [GG];
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS [ErrorNumber], ERROR_MESSAGE() AS [ErrorMessage];
END CATCH;
SELECT 8 AS [HH];
GO
返回值:
"Results" Tab:
DivideByZero
{empty result set}
ErrorNumber ErrorMessage
50000 test, yo!
HH
8