ページの先頭行へ戻る
Enterprise Postgres 12 アプリケーション開発ガイド
FUJITSU Software

D.7.2 sqlca

より強力にエラーを扱うために、埋め込みSQLインタフェースは以下の集合変数であるSQLCA(SQL通信領域)という名前のグローバル変数を提供します。

01  sqlca_t.
    10 sqlcaid PIC X(8).
    10 sqlabc PIC S9(9) COMP-5.
    10 sqlcode PIC S9(9) COMP-5.
    10 sqlerrm.
        20 sqlerrml PIC S9(9) COMP-5.
        20 sqlerrmc PIC X(150).
    10 sqlerrp PIC X(8).
    10 sqlerrd PIC S9(9) COMP-5 OCCURS 6.
    10 sqlwarn PIC X(8).
    10 sqlstate PIC X(5).

(マルチスレッド化されたプログラムでは、各スレッドは自動的にSQLCAのコピーを独自に持ちます。 これは標準Cのerrnoグローバル変数の扱いと同様に動作します。)

SQLCAは警告とエラーの両方を対象としています。 1つのSQL文の実行時に複数の警告やエラーが発生した場合、SQLCAは最後のものに関した情報のみを含みます。

直前のSQL文でエラーがなければ、SQLCODEは0に、SQLSTATEは"00000"になります。 警告やエラーが発生した場合は、SQLCODEは負の値に、SQLSTATEは"00000"以外になります。 正のSQLCODEは、直前の問い合わせが0行を返したなどの無害な条件を示します。 SQLCODEとSQLSTATEは2つの異なるエラーコードスキーマです。 後で詳細に説明します。

直前のSQL文が成功すると、SQLERRD(2)は処理された行のOIDが、もしあれば、格納されます。 また、もしそのコマンドで適切ならば、SQLERRD(3)は処理された、もしくは返された行数が格納されます。

エラーもしくは警告の場合、SQLERRMCには、そのエラーを説明する文字列が格納されます。 SQLERRMLフィールドにはSQLERRMCに格納されたエラーメッセージ長が格納されます (FUNCTION STORED-CHAR-LENGTHの結果です)。 一部のメッセージは固定長のSQLERRMC配列には長過ぎることに注意してください。 この場合は切り詰められます。

警告の場合、SQLWARNの3文字目はWに設定されます (他のすべての場合では、これはW以外の何かに設定されます)。 SQLWARNの2文字目がWに設定された場合、ホスト変数に代入する際に値が切り詰められています。 他の要素が警告を示すように設定された場合、SQLWARNの最初の文字はWに設定されます。

今のところ、SQLCAID、SQLCABC、SQLERRPならびにSQLERRDとSQLWARNの上記以外の要素は有用な情報を持ちません。

SQLCAは標準SQLでは定義されていません。 しかし、複数の他のSQLデータベースシステムで実装されています。 その定義は基本部分は似ていますが、移植性を持つアプリケーションを作成する場合は実装の違いを注意して調査しなければなりません。

ここでWHENEVERとSQLCAを組み合わせて使用して、エラーが発生した時にSQLCAの内容を表示する、1つの例を示します。 これはおそらく、より"ユーザ向け"のエラー処理を組み込む前の、アプリケーションのデバッグまたはプロトタイプで有用です。

EXEC SQL WHENEVER SQLERROR GOTO PRINT_SQLCA END-EXEC.

PRINT_SQLCA.
    DISPLAY "==== sqlca ====".
    DISPLAY "SQLCODE: " SQLCODE.
    DISPLAY "SQLERRML: " SQLERRML.
    DISPLAY "SQLERRMC: " SQLERRMC.
    DISPLAY "SQLERRD: " SQLERRD(1) " " SQLERRD(2) " " SQLERRD(3)" " SQLERRD(4) " "
SQLERRD(5) " " SQLERRD(6).
    DISPLAY "SQLSTATE: " SQLSTATE.
    DISPLAY "===============".

結果は以下のようになります(ここでのエラーはテーブル名の誤記述によるものです)。

==== sqlca ====
sqlcode: -000000400
SQLERRML: +000000064
SQLERRMC: relation "pg_databasep" does not exist (10292) on line 93
sqlerrd: +000000000 +000000000 +000000000 +000000000 +000000000 +000000000
sqlstate: 42P01
===============