SQL Server のエラーメッセージを理解する
SQL Server のエラーメッセージ
エラーの起こし方をご紹介しようと思ったのですが、その前に Exception が起こった時などに SQL Server が出力するエラーメッセージについて、それぞれどんな意味を持っているのか、確認しておきたいと思います。
エラーメッセージを理解する
たとえば、ゼロで割った時に出るエラーメッセージを見てみましょう。
以下のようなストアドプロシジャーを作って、実行してみます。
----------------------------
CREATE PROCEDURE uspErrorMessageTest1
AS
BEGIN
SELECT 1 / 0;
END
----------------------------
EXEC uspErrorMessageTest1;
-- Messages --
Msg 8134, Level 16, State 1, Procedure uspErrorMessageTest1, Line 5
Divide by zero error encountered.
----------------------------
CREATE PROCEDURE uspErrorMessageTest1
AS
BEGIN
SELECT 1 / 0;
END
----------------------------
EXEC uspErrorMessageTest1;
-- Messages --
Msg 8134, Level 16, State 1, Procedure uspErrorMessageTest1, Line 5
Divide by zero error encountered.
----------------------------
出力されるエラーメッセージは 6 個の部分から成り立っています。 それぞれ見ていきましょう。
Msg 8134 - ERROR_NUMBER
Msg 8134 は Error Number です。このエラー番号の定義は以下のクエリーで確認することができます。
SELECT *
FROM sys.messages
WHERE message_id = 8134
AND language_id = 1033; -- 英語: 1033 / 日本語: 1041
FROM sys.messages
WHERE message_id = 8134
AND language_id = 1033; -- 英語: 1033 / 日本語: 1041
50000 番以下は System Error Messages として定義されているので、
ユーザー定義のエラーを作る際は 50000 番より上の数字を選びましょう。
Level 16 - ERROR_SEVERITY
Level 16 の部分はそのエラーの重大度を表しています。ポイントだけ書き留めておきます。
- 0~10 は情報や警告程度のは重大ではないエラーです。 TRY...CATCH を使った時に 10 以下は CATCH に飛びません。
- 11~16 はユーザーが訂正できる一般的なエラーです。
- 17~24 はリソースやハードウエア等の問題でアドミニストレーターが解決しなければならないようなエラーです。
- 20~25 は重大なエラーで接続が切断されます。
- 19~24 が起こると SQL Server のエラーログに出力されます。
詳しくは以下の MSDN のページでご確認ください。
-> [MSDN] データベース エンジン エラーの重大度
State 1 - ERROR STATE
同じエラーでも起こる状況が違うケースがあるので、エラーが起こった状況を特定するためにアサインされているコードです。Microsoft Knowledge Base を参照する時や、SQL Server のサポートエンジニアが問題の箇所を特定する際に役立ちます。
Procedure uspErrorMessageTest1 - ERROR_PROCEDURE
エラーが起こったストアドプロシジャー名前です。 エラーが起こったのがストアドプロシジャー内でない場合は何も返ってきません。
Line 5 - ERROR_LINE
エラーが起こったライン番号です。
Divide by zero error encountered. - ERROR_MESSAGE
最後に、起こったエラーの内容です。TRY...CATCH でエラー情報の取得
上記のエラー情報を取得するには、TRY...CATCH を使い、CATCH でそれぞれ以下の関数を使うことによって取得することができます。
先程も書きましたが、severity が 10 以下の場合は CATCH に飛びませんので、この方法では取得できません。
SELECT ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage;
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage;