データベース千夜一夜第31回

ストアドプロシージャ(5)~補足・CASE関数とエラー処理 長谷川裕行
有限会社 手國堂

エラー処理の補足~sysmessagesテーブル

SQL Serverにはエラーメッセージを保存したテーブル「sysmessages」が用意されています。これを利用すれば、エラー番号に対応したメッセージが取り出せます。


- @@ERRORを使ったエラー処理 -

本コラムの第29回で、エラー発生時にそのエラーコード(エラー番号)を取得する@@ERROR関数を紹介しました。また第30回では、以下のようなストアドプロシージャ“YearlyTransfer4”で、@@ERRORを使ったエラー処理の例を紹介しました。

Create Procedure YearlyTransfer4
As
DECLARE @ErrCode int -- エラー番号を保存する変数
SELECT * INTO 累積売上_old FROM 累積売上_dmy
If @@ERROR = 0
Begin
DELETE 累積売上_dmy
If @@ERROR = 0
Begin
Print '処理は完了しました。'
Set @ErrCode = 0 -- エラー番号を変数に保存
End
Else
Begin
Print '削除操作でエラーが発生しました。'
Set @ErrCode = @@ERROR -- エラー番号を変数に保存
End
End
Else
Begin
Print 'コピー操作でエラーが発生しました。'
Set @ErrCode = @@ERROR -- エラー番号を変数に保存
End
Return @ErrCode -- エラー番号を返す


- メッセージを保存したテーブル -

クエリアナライザでストアドプロシージャの実行を含むSQL文を実行した場合、もしエラーが発生すればメッセージペインにエラー番号とエラーメッセージが表示されます。しかしアプリケーションレベルでは、突然データベースサーバーからのエラーメッセージが表示され、その後はアプリケーションのエラー処理に制御が移ります。

そのエラー処理の中で状況に応じて処理を切り替えるなら、データベース・サーバーから返ってきたエラー番号(@@ERRORの戻り値)を参照することになります。この段階でユーザーに分かりやすい(アプリケーションに適した)エラーメッセージを表示させることができれば、アプリケーションはさらに使いやすくなるでしょう。

発生したエラーに対応するデータベース・サーバー側のメッセージを取得するには、データベース「master」の「sysmessages」テーブルを利用します。「sysmessages」テーブルの各フィールドは、次のような意味を持っています。

表1:「sysmessages」テーブルのフィールド構成
フィールド 意味
error int エラー番号
severity smallint エラーの重大度レベル
dlevel smallint 内部で使用
description nvarchar(255) エラーメッセージ★1
mslangid smallint システムメッセージ・グループ★2
★1 メッセージ中にテーブル名や計数など状況に応じて変化する値を挿入するため、%1、%dなどの代入変数が含まれます。
★2 メッセージに使用する言語を示すIDで、インストール時に言語が正しく設定してあれば、日本では英語(1033)と日本語(1041)の2種類のメッセージが組み込まれます。


- 番号からメッセージを導く -

「sysmessages」テーブルの「error」フィールドの値が、@@ERRORの返すエラー番号に対応しています。同じエラー番号が2つあるのは、「description」フィールドの文字列に日本語と英語があるためです。言語の違いは「msglangid」の値で判別できます。1033は英語、1041が日本語です。

アプリケーション側でデータベースのエラーメッセージを取得する場合、以下のようにmaster.sysmessagesテーブルに対して@@ERROR関数の戻り値をキーにSELECT命令を発行します。

SELECT msgid, description 
FROM master.sysmessages
WHERE msgid = @@ERROR AND msglangid = 1041

これを、以下のようにストアドプロシージャにしておけば、アプリケーションで簡単に利用できます。

Create Procedure GetErrorMessage
@ErrNum int
As
SELECT msgid, description
FROM master.sysmessages
WHERE msgid = @ErrNum AND msglangid = 1041

@ErrNumはプロシージャの引数で、ここにエラー番号を指定します。従ってこのプロシージャは、アプリケーションのエラー処理内で以下のようにして呼び出すことになります。

  EXECUTE GetErrorMessage @@ERROR




トップページ
制御構造の補足~Case関数
エラー処理の補足~sysmessagesテーブル
@@ERRORを使ったエラー処理
メッセージを保存したテーブル
番号からメッセージを導く
エラー処理の補足~RAISERROR命令
あとがき
Copyright © GrapeCity inc. All rights reserved.