red*_*alx 1 sql-server-2008-r2 raiserror
我刚刚遇到了 SQL 的一部分,它的行为与我预期的不同(请参阅下面的有关 SQL 的提炼版本,该版本演示了问题模式)。
(这是在 SQL Server 2008 R2 SP2 64 位上)
“在这里做一些工作”部分会引发错误并触发 CATCH 块中的错误处理。错误编号为 515(尝试将空值插入不可为空的列),因此 RAISERROR 报告错误,但随后循环继续,再次尝试工作,在无限循环中引发错误等。
我希望 RAISERROR 导致执行退出循环。这里发生了什么?
谢谢
WHILE (@Applied <> 1)
BEGIN
BEGIN TRY
-- === Do some work here ===
-- Successfully applied
SET @Applied = 1;
END TRY
BEGIN CATCH
-- Save the error details
SELECT
@ErrorNumber = ERROR_NUMBER(),
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
-- Test for a deadlock or uncommittable transaction
IF (@ErrorNumber = 1205 OR @ErrorNumber = 3930)
-- Sleep for 5 seconds
WAITFOR DELAY '00:00:05';
ELSE
RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH
END
Run Code Online (Sandbox Code Playgroud)
RAISERROR
通常不会停止执行。 THROW确实如此,但这是在 SQL 2012 中引入的。
将一个RETURN;
或RETURN -1;
之后RAISERROR
。
以下内容摘自RAISERROR的 MSDN 页面的“备注”部分:
当 RAISERROR 在 TRY 块中以 11 或更高的严重性运行时,它会将控制转移到关联的 CATCH 块。如果运行 RAISERROR,错误将返回给调用者:
- 在任何 TRY 块的范围之外。
- TRY 块中的严重性为 10 或更低。
- 严重性为 20 或更高的终止数据库连接。
下面是对行为的简单测试。如果在 2012 年之前的 SQL Server 版本上运行,请注释掉或删除带有THROW
.
RAISERROR(N'This is from RAISERROR - Severity 16', 16, 1);
PRINT N'----- 1';
;THROW 50505, N'This is from THROW', 1;
PRINT N'----- 2';
GO
PRINT N'----- 3';
-- WITH LOG needed for severity > 18
RAISERROR(N'This is from RAISERROR - Severity 20', 20, 1) WITH LOG;
PRINT N'----- 4';
GO
PRINT N'----- 5';
Run Code Online (Sandbox Code Playgroud)
上述测试在“消息”选项卡中返回以下内容:
Msg 50000, Level 16, State 1, Line 2
这是来自 RAISERROR - Severity 16
----- 1
Msg 50505, Level 16, State 1, Line 5
这是来自 THROW
----- 3
Msg 2745, Level 16 ,状态 2,第 4 行
进程 ID 54 引发了用户错误 50000,严重性为 20。SQL Server 正在终止此进程。
Msg 50000, Level 20, State 1, Line 4
这是来自 RAISERROR - Severity 20
Msg 0, Level 20, State 0, Line 0
当前命令发生严重错误。结果,如果有的话,应该被丢弃。
在 SSMS 的左下角,它将指示“已断开连接”。
归档时间: |
|
查看次数: |
18031 次 |
最近记录: |