RDBMSにはそれぞれ独自のエラーコード体系(Oracleで言えば"ORA-xxxxx")があり、これらのエラーコードを判別して、エラーのハンドリングを行うのが一般的です。
ところが、接続エラーなどの場合にはエラーコードが返されないこともあります。
このような場合、単純に”システムエラー”とか”データベースアクセスエラー”として処理を中断してもよいのであればそれでいいですが、そうもいかない場合にはSQLSTATE値で判別します。
SQLSTATE値はSQLの実行状態を表す値で、X/OPEN(SQL92)で定義されたSQLSTATE値、またはSQL99で定義されたSQLSTATE値のいずれかを返します。
両者はSQL規格の新旧が異なるだけで基本的には同じコード体系です。
SQLSTATE値は5文字のコードです。
このコードは2つの部分に分けられ、上位2文字はクラス、下位3文字はサブクラスを表します。
クラスとサブクラスはそれぞれ標準クラスと実装定義のクラスに分けられ、標準クラス(またはサブクラス)はX/OPEN(SQL92)またはSQL99で事前定義されたSQLSTATE値、実装定義のクラス(またはサブクラス)はRDBMS製品で定義されたSQLSTATE値を表します。
標準クラスと実装定義のクラスはそれぞれ名前空間が以下のように予約されています。
- 標準クラス(またはサブクラス):クラス(またはサブクラス)の1文字目が'0'から'4'または'A'~'H'
- 実装定義のクラス(またはサブクラス):クラス(またはサブクラス)の1文字目が'5'~'9'または'I'~'Z'
Javaの場合、SQLSTATE値はSQLExceptionのgetSQLState()で取得することができます。
(ちなみにエラーコードはgetErrorCode()で取得できます)
ということで、SQLSTATE値でエラーハンドリングしたい場合は、SQLExceptionをcatchしてgetSQLState()し、その値に応じてエラー処理を行えばOKです。
[注意]
SQLSTATE値にはRDBMSに依存する実装定義のクラスが存在するため、同じエラーでもRDBMSごとに異なるSQLSTATE値を返すというケースが出てきます。
また、返されるSQLSTATE値以前に、同じ操作を行った結果起こったエラーを何のエラーと解釈するかも実装(RDBMS)次第です。
そのため、マルチRDBMS対応のシステムでは各RDBMSがどんな値を返すかをしっかりテストし、もし同じエラーで違うSQLSTATE値が返るようであれば、RDBMSを区別してエラーハンドリングを行わなければなりません。
[参考文献]