エラー処理¶
ECPGPlusは、埋め込みSQLコードのエラーを検出して処理するための2つの方法を提供します。
クライアントアプリケーションは、エラーメッセージの
sqlcaデータ構造を調べ、クライアントアプリケーションにカスタマイズされたエラー処理を提供できます。クライアントアプリケーションには、ECPGPlusコンパイラにエラー処理コードを追加するよう指示する
EXEC SQL WHENEVERディレクティブを含めることができます。
sqlcaでのエラー処理¶
sqlca (SQL通信領域)は、 ecpglib がサーバーからクライアントアプリケーションに情報を伝達するために使用するグローバル変数です。SQLステートメント( INSERT または SELECT ステートメントなど)を実行した後、 sqlca の内容を調べて、ステートメントが正常に完了したか、ステートメントが失敗したかを判断できます。
sqlca の構造は次のとおりです。
struct
{
char sqlcaid[8];
long sqlabc;
long sqlcode;
struct
{
int sqlerrml;
char sqlerrmc[SQLERRMC_LEN];
} sqlerrm;
char sqlerrp[8];
long sqlerrd[6];
char sqlwarn[8];
char sqlstate[5];
} sqlca;
次のディレクティブを使用して、 sqlca 機能を実装します。
EXEC SQL INCLUDE sqlca;
ecpg ディレクティブを含める場合、クライアントアプリケーションのヘッダー宣言に sqlca.h ファイルを #include する必要はありません。
AdvancedServerの sqlca 構造には、次のメンバーが含まれます。
sqlcaid
sqlcaidには文字列/"SQLCA/"が含まれます。
sqlabc
sqlabcにはsqlca構造のサイズが含まれます。
sqlcode
sqlcodeメンバーはSQL92で非推奨になりました。AdvancedServerは下位互換性のためにsqlcodeをサポートしますが、新しいコードを記述するときはsqlstateメンバーを使用する必要があります。
sqlcodeは整数値です。正のsqlcode値は、クライアントアプリケーションが無害な処理条件に遭遇したことを示し、負の値は警告またはエラーを示します。ステートメントがエラーなしで処理される場合、
sqlcodeには0の値が含まれます。クライアントアプリケーションがステートメントの実行中にエラー(または警告)に遭遇した場合、sqlcodeには最後に返されたコードが含まれます。SQL標準では、正の値100のみが定義されています。これは、処理された最新のSQLステートメントが返された/影響を受けた行がないことを示します。標準SQLでは他の
sqlcode値を定義していないため、各条件に割り当てられる値はデータベースごとに異なる可能性があることに注意してください。
sqlerrm は sqlca 内に埋め込まれた構造で、2つのメンバーで構成されます。
sqlerrml
sqlerrmlには、sqlerrmcに現在保存されているエラーメッセージの長さが含まれます。
sqlerrmc
sqlerrmcには、sqlstateに保存されているコードに関連付けられたヌル終了メッセージテキストが含まれます。メッセージの長さが149文字を超える場合、ecpglibはエラーメッセージを切り捨てます。
sqlerrp
sqlerrpには/"NOT SET/"という文字列が含まれます。
sqlerrd は、6つの要素を含む配列です。
sqlerrd[1]には、処理された行のOIDが含まれます(該当する場合)。
sqlerrd[2]には、処理または返された行の数が含まれます。
sqlerrd[0], sqlerrd[3], sqlerrd[4]とsqlerrd[5]は未使用です。
sqlwarn は8文字を含む配列です。
sqlwarn内の他の要素が'W'に設定されている場合、sqlwarn[0]には'W'の値が含まれます。データ値がホスト変数に格納されたときに切り捨てられた場合、
sqlwarn[1]には'W'の値が含まれます。クライアントアプリケーションが致命的でない警告を検出した場合、
sqlwarn[2]には'W'の値が含まれます。
sqlwarn[3], sqlwarn[4], sqlwarn[5], sqlwarn[6]およびsqlwarn[7]は未使用です。
sqlstate
sqlstateは、クライアントアプリケーションからステートメントを実行した後のSQL準拠のステータスコードを含む5文字の配列です。ステートメントがエラーなしで処理される場合、sqlstateには00000の値が含まれます。sqlstateはヌル終端文字列ではないことに注意してください。
sqlstateコードは階層スキームで割り当てられます:
sqlstateの最初の2文字は、条件の一般的なクラスを示します。
sqlstateの最後の3文字は、クラス内の特定のステータスを示します。クライアントアプリケーションがSQLステートメントの実行中に複数のエラー(または警告)に遭遇した場合、
sqlstateには返された最後のコードが含まれます。
次の表に、 sqlstate と sqlcode の値、および関連する条件のシンボル名とエラーの説明を示します。
sqlstate |
sqlcode (非推奨) |
記号名 |
説明 |
|---|---|---|---|
YE001 |
-12 |
ECPG_OUT_OF_MEMORY |
仮想メモリが枯渇しています。 |
YE002 |
-200 |
ECPG_UNSUPPORTED |
プリプロセッサが認識されないアイテムを生成しました。プリプロセッサとライブラリ間の非互換性を示している可能性があります。 |
07001、または07002 |
-201 |
ECPG_TOO_MANY_ARGUMENTS |
プログラムは、コマンドが予想するよりも多くの変数を指定します。 |
07001、または07002 |
-202 |
ECPG_TOO_FEW_ARGUMENTS |
プログラムが指定した変数がコマンドの予想よりも少ない。 |
21000 |
-203 |
ECPG_TOO_MANY_MATCHES |
SQLコマンドは複数の行を返しましたが、ステートメントは単一の行を受け取る準備ができていました。 |
42804 |
-204 |
ECPG_INT_FORMAT |
ホスト変数(Cコードで定義されている)はINT型であり、選択されたデータはINTに変換できない型です。ecpglibは、strtol()関数を使用して文字列値を数値形式に変換します。 |
42804 |
-205 |
ECPG_UINT_FORMAT |
ホスト変数(Cコードで定義)は符号なしINTであり、選択されたデータは符号なしINTに変換できないタイプです。ecpglibは、strtoul()関数を使用して文字列値を数値形式に変換します。 |
42804 |
-206 |
ECPG_FLOAT_FORMAT |
ホスト変数(Cコードで定義)はFLOAT型であり、選択されたデータはFLOATに変換できない型です。ecpglibはstrtod()関数を使用して、文字列値を数値形式に変換します。 |
42804 |
-211 |
ECPG_CONVERT_BOOL |
ホスト変数(Cコードで定義)はBOOL型であり、選択したデータをBOOLに保存することはできません。 |
YE002 |
-2-1 |
ECPG_EMPTY |
サーバーに送信されたステートメントは空でした。 |
22002 |
-213 |
ECPG_MISSING_INDICATOR |
サーバーから返されたNULL値にNULLインジケーター変数が指定されていません(クライアントアプリケーションが予期しないNULL値を受信しました)。 |
42804 |
-214 |
ECPG_NO_ARRAY |
サーバーは配列を返しました。対応するホスト変数は配列を格納できません。 |
42804 |
-215 |
ECPG_DATA_NOT_ARRAY |
サーバーは、配列値を予期するホスト変数に配列ではない値を返しました。 |
08003 |
-220 |
ECPG_NO_CONN |
クライアントアプリケーションは、存在しない接続を使用しようとしました。 |
YE002 |
-221 |
ECPG_NOT_CONN |
クライアントアプリケーションは、割り当てられたが閉じられた接続を使用しようとしました。 |
26000 |
-230 |
ECPG_INVALID_STMT |
ステートメントは準備されていません。 |
33000 |
-240 |
ECPG_UNKNOWN_DESCRIPTOR |
指定された記述子が見つかりません。 |
07009 |
-241 |
ECPG_INVALID_DESCRIPTOR_INDEX |
記述子のインデックスが範囲外です。 |
YE002 |
-242 |
ECPG_UNKNOWN_DESCRIPTOR_ITEM |
クライアントアプリケーションが無効な記述子項目を要求しました(内部エラー)。 |
07006 |
-243 |
ECPG_VAR_NOT_NUMERIC |
動的ステートメントが、非数値ホスト変数の数値を返しました。 |
07006 |
-244 |
ECPG_VAR_NOT_CHAR |
動的SQLステートメントがCHAR値を返しましたが、ホスト変数はCHARではありません。 |
/ |
-400 |
ECPG_PGSQL |
サーバーがエラーメッセージを返しました。結果のメッセージにはエラーテキストが含まれます。 |
08007 |
-401 |
ECPG_TRANS |
サーバーは、指定されたトランザクションを開始、コミット、またはロールバックできません。 |
08001 |
-402 |
ECPG_CONNECT |
クライアントアプリケーションがデータベースに接続しようとして失敗しました。 |
02000 |
100 |
ECPG_NOT_FOUND |
最後のコマンドが行を取得または処理しなかったか、カーソルの終わりに達しました。 |
EXECSQLWHENEVER¶
EXEC SQL WHENEVER ディレクティブを使用して、ECPGPlusでコンパイルされたクライアントアプリケーションに簡単なエラー処理を実装します。ディレクティブの構文は次のとおりです。
EXEC SQL WHENEVER <condition> <action>;
このディレクティブは、エラー処理コードをプログラムに挿入するようにECPGコンパイラーに指示します。
このコードは、クライアントアプリケーションが特定の条件を検出した場合に、指定されたアクションを実行するようにクライアントアプリケーションに指示します。条件 は次のいずれかです。
SQLERROR
sqlca.sqlcodeがゼロ未満の場合、SQLERROR条件が存在します。
SQLWARNING
sqlca.sqlwarn[0]に'W'が含まれる場合、SQLWARNING条件が存在します。
NOT FOUND
sqlca.sqlcodeがECPG_NOT_FOUNDの場合(クエリがデータを返さない場合)、NOT FOUND条件が存在します。
前の条件のいずれかに遭遇した場合、クライアントアプリケーションが次の*アクション* のいずれかを実行するように指定できます。
CONTINUE
CONTINUEを指定して、現在のconditionを無視して、クライアントアプリケーションに処理を続行するよう指示します。CONTINUEがデフォルトのアクションです。
DO CONTINUE
DO CONTINUEのアクションは、放出されたCコードにCONTINUEステートメントを生成します。条件に遭遇すると、ループ内の残りのコードをスキップし、次の反復を続行します。ループ内でのみ使用できます。
GOTO label
または
GO TO label
Cの
gotoステートメントを使用して、指定したlabelにジャンプします。
SQLPRINT
sqlprint()関数を使用して、エラーメッセージをstderr(標準エラー)に出力します。sqlprint()関数はsql errorを出力し、その後にsqlca.sqlerrm.sqlerrmcの内容が続きます。
STOP
exit(1)を呼び出してエラーを通知し、プログラムを終了します。
DO BREAK
Cの
breakステートメントを実行します。このアクションは、ループまたはswitchステートメントで使用します。
CALL name(args)
または
DO name(args)
argsパラメーターで指定されたパラメーターを使用して、parameterという名前で指定されたC関数を呼び出します。
Example:
次のコードは、クライアントアプリケーションで警告が発生した場合にメッセージを出力し、エラーが発生した場合にアプリケーションを中止します。
EXEC SQL WHENEVER SQLWARNING SQLPRINT;
EXEC SQL WHENEVER SQLERROR STOP;
注釈
クライアントアプリケーションが上から下に*実行* できない場合でも、ECPGPlusコンパイラはプログラムを上から下に処理します。コンパイラ指令は各行に順番に適用され、コンパイラが別の指令に遭遇するまで有効です。プログラム内のフローの制御が上から下にない場合は、コンパイル中に誤って見落とされる可能性のあるプログラムの部分にエラー処理ディレクティブを追加することを検討する必要があります。