我最好的谷歌结果是这样的:
- 11 以下是警告,而不是错误
- 11-16可用
- 以上16个是系统错误
- 11-16之间没有行为差异
但是,根据 BOL,“任何用户都可以指定从 0 到 18 的严重级别”。
在我的特定存储过程中,我希望将错误返回给 .Net 客户端应用程序,因此看起来 11-18 之间的任何严重级别都可以解决问题。是否有人对每个级别的含义以及应如何使用它们有任何权威信息?
我最好的谷歌结果是这样的:
但是,根据 BOL,“任何用户都可以指定从 0 到 18 的严重级别”。
在我的特定存储过程中,我希望将错误返回给 .Net 客户端应用程序,因此看起来 11-18 之间的任何严重级别都可以解决问题。是否有人对每个级别的含义以及应如何使用它们有任何权威信息?
您应该返回 16。这是默认的、最常用的错误级别:
表示用户可以更正的一般错误。
不要返回 17-18,那些表示更严重的错误,例如资源问题:
表示用户无法纠正的软件错误。将问题通知您的系统管理员。
也不要返回 11-15,因为它们具有附加到每个级别的特殊含义(14 - 安全访问,15 - 语法错误,13 - 死锁等)。
级别 16 不会终止执行。
如果您打算记录警告但继续执行,请改用低于 10 的严重性级别。
严重级别16
可以终止执行。
RAISERROR()
严重性为16的将终止对违规行以下的所有内容的执行。
但是,这只适用于 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都是一样的。
如果您取消注释最顶部的除零线,那么它下面的任何内容都不会运行。
除零逻辑也将生成严重性为16的异常,
但它是用句号处理的,与抛出时不同RAISERROR()
。
注意:;THROW
用作 Catch-Block 中的最后一行,以正确抛出由 Try-Block 触发
的事件的 SQL 异常。
这将有效地停止执行。
当调用之前 Catch-Block 中存在其他行时,分号是必需的。
如果您的逻辑正确处理了 Catch-Block 中的错误(并且您希望继续处理
之后的其余逻辑),则不要使用.RAISERROR()
;
;THROW
;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
,您可能永远不知道您的信息消息何时会出现。
它们可能在整个批次过程中间歇出现,或者在批次完成时同时出现。