web-dev-qa-db-ja.com

異なるRAISERROR重大度レベルは何を意味しますか?

私の最高のグーグルの結果は this

  • 11以下は警告であり、エラーではありません
  • 11-16は使用可能です
  • 16以上はシステムエラーです
  • 11-16の間に行動の違いはありません

しかし、BOLからは、「0〜18の重大度レベルはどのユーザーでも指定できます。」

私の特定のストアドプロシージャでは、エラーを.Netクライアントアプリケーションに返す必要があるため、11〜18の重大度レベルで問題が発生するようです。各レベルの意味、およびそれらの使用方法に関する信頼できる情報はありますか?

69
Steve S.

データベースエンジンの重大度

16を返す必要があります。デフォルトで、最も使用されるエラーレベルは次のとおりです。

ユーザーが修正できる一般的なエラーを示します。

17〜18を返さないでください。リソースの問題など、より深刻なエラーを示しています。

ユーザーが修正できないソフトウェアエラーを示します。システム管理者に問題を通知してください。

また、11-15を返さないでください。これらは各レベルに特別な意味があります(14-セキュリティアクセス、15-構文エラー、13-デッドロックなど)。

レベル16は実行を終了しません。

警告を記録し、実行を継続する場合は、代わりに10未満の重大度レベルを使用します。

101
Remus Rusanu

重大度レベル_16_ can実行を終了します。

RAISERROR()を使用したTRY-CATCH警告:

重大度が16RAISERROR()は、問題のある行の下にあるすべての実行を終了します。
ただし、 thisonlyは、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.
_

びっくりした?私もそうだった。
ループのために私を投げたのは、すべての重大度-16が同じというわけではありません。
最上部のゼロ分割ラインのコメントを外すと、その下に何も実行されません。
ゼロによる除算ロジックは、also重大度-16 Exception、
butRAISERROR()でスローされる場合とは異なり、full-stopで処理されます。

注:として_;THROW_を使用last Catch-Block内の行を適切に
Try Try-BlockによってトリガーされたRAISERROR()イベントに対してSQL例外をスローします。
これは、フルストップで実行を効果的に停止します。
_;_を呼び出す前にCatch-Blockに他の行が存在する場合は、_;THROW_セミコロンが必要です。
Catch-Blockのエラーがロジックで適切に処理されている場合(および処理を続行したい場合
ロジックの残りの部分)、その後notuse _;THROW_を実行します。

結論:

SQL-Server-Engineによってスローされた重大度-16を統合しないでください
RAISERROR()を使用して自分自身を育てます。
すべての意図および目的(意図的に自分のエラーをスローする場合)については、2つの重大度のみを考慮してください。
(情報または警告の場合)および
16(Try-Block内で処理された例外をスローする場合-Catch-Blockにキックアウトするため)。

情報今!

注:RAISERROR()を使用して情報メッセージを表示する場合、
nそして、私は_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
_

これは、洞察力が必要な場合の長時間のバッチ操作で特に役立ちます
バッチ全体で特定のマイルストーンマーカーに到達したときの状況の推移。
notを使用して_WITH NOWAIT_を使用すると、情報メッセージがいつ表示されるかわかりません。
バッチの処理中に断続的に表示されることもあれば、バッチが完了するとすぐに表示されることもあります。

5
MikeTeeVee