プライマリ・コンテンツに移動
Pro*C/C++プログラマーズ・ガイド
12c リリース1(12.1)
B71397-03
目次へ移動
目次
索引へ移動
索引

前
次

SQL通信領域(SQLCA)の使用

SQLCAはデータ構造体です。そのコンポーネントには、SQL文を実行するたびにOracleによって更新されるエラー、警告およびステータス情報が格納されます。したがって、SQLCAには常に最新のSQLの動作結果が反映されます。この結果を判断するために、SQLCA内の変数をチェックすることが可能です。

プログラムでは複数のSQLCAを使用できます。たとえば、1つのグローバルSQLCAと複数のローカルSQLCAを設定できます。ローカルSQLCAへのアクセスは、プログラム内の有効範囲により制限されます。Oracleは、スコープ内にあるSQLCAにのみ情報を戻します。

注意:

アプリケーションでOracle Netを使用してローカル・データベースおよびリモート・データベースの組合せに同時にアクセスする場合、すべてのデータベースは1つのSQLCAに書き込みます。つまり、データベースごとに異なるSQLCAがあるわけではありません

SQLCAの宣言について

MODE=ORACLEのときは、SQLCAの宣言が必要です。SQLCAを宣言するには、次に示すようにINCLUDEまたは#include文を使用してSQLCAをプログラム内にコピーします。

EXEC SQL INCLUDE SQLCA; 

または

#include <sqlca.h>

宣言部を使用するときは、SQLCAは宣言部の外側で宣言する必要があります。SQLCAを宣言しないとコンパイル時にエラーが発生します。

プログラムをプリコンパイルすると、INCLUDE SQLCA文はいくつかの変数宣言に置き換えられます。これらの変数宣言によって、Oracleとプログラムとの間の通信が可能になります。

MODE=ANSIのときは、SQLCAの宣言はオプションです。ただしこのとき、SQLCODEまたはSQLSTATE状態変数は宣言する必要があります。SQLCODE(必ず大文字)の型はintです。特定のコンパイル・ユニットでSQLCAのかわりにSQLCODEまたはSQLSTATEを宣言した場合、プリコンパイラではそのユニット用に内部SQLCAが割り当てられます。Pro*C/C++プログラムは、内部SQLCAにはアクセスできません。SQLCAおよびSQLCODEの両方を宣言すると、OracleはSQL操作を実行するたびに同じステータス・コードを両方に戻します。

注意:

SQLCAの宣言はMODE=ANSIのときにはオプションですが、WHENEVER SQLWARNINGディレクティブはSQLCAがなければ使用できません。したがって、WHENEVER SQLWARNINGディレクティブを使用する場合は、SQLCAを宣言する必要があります。

このマニュアルでは、SQLCODE状態変数を指す場合にSQLCODEを使用しています。また、SQLCA構造体のコンポーネントのことを明示する場合には、sqlca.sqlcodeを使用しています。

SQLCAの内容

SQLCAにはSQL文の実行結果に関する次の情報が格納されます。

  • Oracleエラー・コード

  • 警告フラグ

  • イベント情報

  • 処理済行数

  • 診断

sqlca.hヘッダー・ファイルは次のとおりです。

/*
NAME
  SQLCA : SQL Communications Area.
FUNCTION
  Contains no code. Oracle fills in the SQLCA with status info
  during the execution of a SQL stmt.
NOTES
  **************************************************************
  ***                                                        ***
  *** This file is SOSD.  Porters must change the data types ***
  *** appropriately on their platform.  See notes/pcport.doc ***
  *** for more information.                                  ***
  ***                                                        ***
  **************************************************************

  If the symbol SQLCA_STORAGE_CLASS is defined, then the SQLCA
  will be defined to have this storage class. For example:
 
    #define SQLCA_STORAGE_CLASS extern
 
  will define the SQLCA as an extern.
 
  If the symbol SQLCA_INIT is defined, then the SQLCA will be
  statically initialized. Although this is not necessary in order
  to use the SQLCA, it is a good programing practice not to have
  unitialized variables. However, some C compilers/operating systems
  don't allow automatic variables to be initialized in this manner.
  Therefore, if you are INCLUDE'ing the SQLCA in a place where it
  would be an automatic AND your C compiler/operating system doesn't
  allow this style of initialization, then SQLCA_INIT should be left
  undefined -- all others can define SQLCA_INIT if they wish.

  If the symbol SQLCA_NONE is defined, then the SQLCA
  variable will not be defined at all.  The symbol SQLCA_NONE
  should not be defined in source modules that have embedded SQL.
  However, source modules that have no embedded SQL, but need to
  manipulate a sqlca struct passed in as a parameter, can set the
  SQLCA_NONE symbol to avoid creation of an extraneous sqlca
  variable. 
*/
#ifndef SQLCA
#define SQLCA 1
struct   sqlca
         {
         /* ub1 */ char    sqlcaid[8];
         /* b4  */ long    sqlabc;
         /* b4  */ long    sqlcode;
         struct
           {
           /* ub2 */ unsigned short sqlerrml;
           /* ub1 */ char           sqlerrmc[70];
           } sqlerrm;
         /* ub1 */ char    sqlerrp[8];
         /* b4  */ long    sqlerrd[6];
         /* ub1 */ char    sqlwarn[8];
         /* ub1 */ char    sqlext[8];
         };
#ifndef SQLCA_NONE 
#ifdef   SQLCA_STORAGE_CLASS
SQLCA_STORAGE_CLASS struct sqlca sqlca
#else
         struct sqlca sqlca
#endif
#ifdef  SQLCA_INIT
         = {
         {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '},
         sizeof(struct sqlca),
         0,
         { 0, {0}},
         {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '},
         {0, 0, 0, 0, 0, 0},
         {0, 0, 0, 0, 0, 0, 0, 0},
         {0, 0, 0, 0, 0, 0, 0, 0}
         }
#endif
         ;
#endif
#endif

SQLCAの構造体

この項では、SQLCAの構造体、そのコンポーネントおよびコンポーネントに格納できる値について説明します。

sqlcaid

この文字列コンポーネントはSQLCAに初期化されて、SQL通信領域を示します。

sqlcabc

この整数コンポーネントにはSQLCA構造体の長さがバイト単位で格納されます。

sqlcode

この整数コンポーネントには最後に実行されたSQL文のステータス・コードが格納されます。SQLの動作の結果を示すステータス・コードは、次のいずれかの数値です。

ステータス・コード 説明

0

エラーまたは例外の検出なしで文が実行されたことを示します。

>0

文は実行されたが、例外が検出されたことを示します。この状態が発生するのは、WHERE句の検索条件を満たす行がない場合、あるいはSELECT INTOまたはFETCHで1行も戻されなかった場合です。

MODE=ANSIのときは、どの行もINSERTできなければ+100がsqlcodeに戻されます。副問合せで処理に行が戻されなかったときにこの状態が発生します。

  • <0はデータベース、システム、ネットワークまたはアプリケーションのエラーが原因で、文が実行されなかったことを示します。このようなエラーは致命的です。このようなエラーが発生すると、ほとんどの場合はカレント・トランザクションがロールバックされます。

エラー・コードに対応する負数のリターン・コードは、Oracle Databaseエラー・メッセージに記載されています

sqlerrm

この埋込み構造体には次の2つのコンポーネントがあります。

コンポーネント 説明

sqlerrml

この整数コンポーネントには、sqlerrmc内に保存されているメッセージ・テキストの長さが格納されます。

sqlerrmc

この文字列コンポーネントには、sqlcode内に保存されているエラー・コードに対応したメッセージ・テキストが格納されます。文字列はヌル文字で終了しません。長さを調べるにはsqlerrmlコンポーネントを使用します。

このコンポーネントには最大70文字まで格納できます。71文字以上のメッセージ全体を取得するには、この後で説明するsqlglm関数を使用します。

sqlerrmcを参照する前にsqlcodeが負であることを確認する必要があります。sqlcodeが0(ゼロ)のときにsqlerrmcを参照すると、以前のSQL文に対応するメッセージが取得されることになります。

sqlerrp

この文字列コンポーネントは将来使用するために予約されています。

sqlerrd

この2進整数の配列には6つの要素があります。sqlerrd内のコンポーネントの説明を次に示します。

コンポーネント 説明

sqlerrd[0]

このコンポーネントは将来使用するために予約されています。

sqlerrd[1]

このコンポーネントは将来使用するために予約されています。

sqlerrd[2]

このコンポーネントには、その時点で最後に実行したSQL文によって処理された行数が格納されます。ただし、SQL文が失敗すると、1つの例外を除きsqlca.sqlerrd[2]の値は未定義となります。配列処理中にエラーが発生すると、そのエラーの発生した行で処理は停止します。そのため、sqlca.sqlerrd[2]は正常に処理された行数を示します。

処理済行数はOPEN文の後に0 (ゼロ)に設定され、FETCH文の後に増分されます。処理済行数は、EXECUTE文、INSERT文、UPDATE文、DELETE文およびSELECT INTO文について、正常に処理された行数を反映します。この数には、UPDATEやDELETE_CASCADEで処理された行は含まれません。たとえばWHERE句の条件を満たす20行が削除された後で、列制約条件に違反する5行が削除されたときの処理済行数は、25ではなく20となります。

コンポーネント 説明

sqlerrd[3]

このコンポーネントは将来使用するために予約されています。

sqlerrd[4]

このコンポーネントは、最後に実行されたSQL文中で解析エラーの始まりを示す文字位置を指定するオフセットを保持します。先頭の文字位置は0 (ゼロ)です。

sqlerrd[5]

このコンポーネントは将来使用するために予約されています。

sqlwarn

この1文字の配列には8つの要素があります。これらの要素は警告フラグとして使用されます。Oracleではそれに文字値W(警告)を割り当てることでフラグを設定します。

フラグは例外状態の発生を警告します。たとえば、切り捨てられた列値が出力ホスト変数に割り当てられると、警告フラグが設定されます。

sqlwarnのコンポーネントの説明を次に示します。

コンポーネント 説明

sqlwarn[0]

このフラグは別の警告フラグが設定されていることを示します。

sqlwarn[1]

このフラグは、切り捨てられた列値が出力ホスト変数に代入されたときに設定されます。これは文字データにのみ適用されます。つまり、Oracleは、警告で設定することも負のsqlcodeを戻すこともなく、特定の数値データを切り捨てます。

列値が切り捨てられたかどうか、またどれだけ切り捨てられたかを調べるには、出力ホスト変数に対応する標識変数をチェックします。標識変数によって戻された値が正の整数のときは、その値は列値の元の長さを示します。その値に応じてホスト変数の長さを増やすことができます。

コンポーネント 説明

sqlwarn[2]

AVG()やSUM()などのSQLグループ関数の結果にNULL列が使用されない場合、このフラグが設定されます。

sqlwarn[3]

問合せの選択リスト内の列の数がSELECT文またはFETCH文のINTO句内のホスト変数の数と一致しないときに、このフラグが設定されます。戻される項目の数は両者のうち少ない方の数となります。

sqlwarn[4]

このフラグは現在使用されていません。

sqlwarn[5]

PL/SQLのコンパイル・エラーが原因でEXEC SQL CREATE {PROCEDURE | FUNCTION | PACKAGE | PACKAGE BODY}文が失敗したときに、このフラグが設定されます。

sqlwarn[6]

このフラグは現在使用されていません。

sqlwarn[7]

このフラグは現在使用されていません。

sqlext

この文字列コンポーネントは将来使用するために予約されています。

PL/SQLに関する考慮事項

プリコンパイラ・アプリケーションで埋込みPL/SQLブロックを実行するときに、SQLCAのすべてのコンポーネントが設定されるわけではありません。たとえば、ブロックが複数の行をフェッチするときは、処理済行数(sqlerrd[2])には1しか設定されません。PL/SQLブロックの実行後は、SQLCAのsqlcodeおよびsqlerrmコンポーネントのみを使用してください。