RAISERROR严重程度不同意味着什么?

问题描述 投票:67回答:2

我最好的谷歌结果是this

  • 低于11是警告,而不是错误
  • 11-16可供使用
  • 16以上是系统错误
  • 11-16之间没有行为差异

但是,从BOL,“任何用户都可以指定从0到18的严重级别”。

在我的特定存储过程中,我希望将错误返回到.Net客户端应用程序,因此看起来11-18之间的任何严重性级别都可以解决问题。有没有人有关于每个级别的含义以及如何使用它们的任何权威信息?

sql-server raiserror
2个回答
99
投票

Database Engine Severity Levels

您应该返回16.是默认的,最常用的错误级别:

表示可由用户更正的一般错误。

不要返回17-18,那些表示更严重的错误,如资源问题:

指出用户无法纠正的软件错误。通知您的系统管理员该问题。

也不要返回11-15,因为它们具有附加到每个级别的特殊含义(14 - 安全访问,15 - 语法错误,13 - 死锁等)。

16级不会终止执行。

如果您打算记录警告但继续执行,请使用低于10的严重性级别。


1
投票

严重级别16可以终止执行。

带有RAISERROR()的TRY-CATCH警告:

严重性为16的RAISERROR()终止执行违规行以下的所有内容。 但是,这仅适用于Try-Block内部。

--DECLARE @DivideByZero Int = 1/0--Uncommenting this will Skip everything below.
RAISERROR (N'Before Try: Raise-Error 16.', 16, 0)--Works.
SELECT 'Before Try: Select.'[Marker]--Works.
BEGIN TRY
    RAISERROR (N'Inside Try: Raise-Error 16.', 16, 0)--Not displayed,but sends to Catch-Block.
    SELECT 'Inside Try: Select.'[Marker]--Skipped.
END TRY
BEGIN CATCH
    RAISERROR (N'Inside Catch: Raise-Error 16.', 16, 0)--Works.
    SELECT 'Inside Catch: Select.'[Marker]--Works.
    --RETURN --Adding Return will only skip what is After the Catch-Block for this scope only.
    --;THROW--Shows the RAISERROR() from the Try-Block and Halts Execution. Must include ";".
END CATCH
RAISERROR (N'After Try-Catch: Raise-Error 16.', 16, 0)--Works.
SELECT 'After Try-Catch: Select.'[Marker]--Works.

惊讶吗?我也是。 什么也让我徘徊不是所有Severity-16都是一样的。 如果你要在最顶层取消注释除零线,那么它下面的任何东西都不会运行。 Divide-By-Zero逻辑也会产生Severity-16 Exception, 但它是一个完整的处理,不像与RAISERROR()抛出。

注意:正确使用;THROW作为Catch-Block中的最后一行 抛出由Try-Block触发的RAISERROR()事件的SQL异常。 这将有效地停止执行。 在调用;之前,当Catch-Block中存在其他行时,需要;THROW分号。 如果您的逻辑正确处理Catch-Block中的错误(并且您希望继续处理 其余的逻辑之后),然后不要使用;THROW

结论:

不要混淆SQL-Server-Engine抛出的Severity-16 用一个你用RAISERROR()提高自己。 对于所有意图和目的(故意抛出自己的错误),只考虑2个严重程度: 0(用于信息或警告)和 16(用于在Try-Block中处理异常 - 将其踢出Catch-Block)。

信息现在!

注意:如果您使用RAISERROR()显示信息性消息, 然后我建议使用WITH NOWAIT

RAISERROR('Read me right now!', 0, 1) WITH NOWAIT
RAISERROR('Read me whenever.' , 0, 1)
DECLARE @WaitSeconds Int = 10
DECLARE @WaitFor DateTime = DATEADD(SECOND, @WaitSeconds, 0)
WAITFOR DELAY @WaitFor

当您需要一些见解时,这在长批量操作中尤其有用 当您在整个批次中达到某些里程碑标记时,事情如何进展。 如果不使用WITH NOWAIT,您可能永远不会知道何时可能出现您的信息消息。 它们可以在整个批处理过程中间歇出现,或者在批处理完成时立即出现。

© www.soinside.com 2019 - 2024. All rights reserved.