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

前
次

Oracle通信領域(ORACA)の使用について

SQLCAが標準的なSQL通信を処理するのに対し、ORACAはOracle通信を処理します。ランタイム・エラーおよび状態の変化について、SQLCAで提供されるより詳しい情報が必要な場合は、ORACAを使用してください。これには、豊富な診断ツールが用意されています。ただし、ORACAの使用はランタイム・オーバーヘッドを増加させるため、あくまでもオプションです。

ORACAは問題の診断に役立つ上に、プログラムによるOracleリソース(SQL文エグゼキュータやカーソル・キャッシュなど)の利用を監視できます。

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

ORACAの宣言について

ORACAを宣言するには、次に示すように、INCLUDE文または#includeプリプロセッサ・ディレクティブを使用してORACAを自分のプログラムにコピーします。

EXEC SQL INCLUDE ORACA; 

または

#include <oraca.h> 

ORACAがextern記憶域クラスであることが必要な場合は、プログラムに次のようにORACA_STORAGE_CLASSを定義します。

#define ORACA_STORAGE_CLASS extern

プログラムで宣言部を使用するときは、ORACAを宣言部の外側で定義する必要があります。

ORACAの有効化について

ORACAを有効にするには、コマンドラインに次のようにORACAオプションを指定する必要があります。

ORACA=YES 

またはインラインで次のように指定します。

EXEC ORACLE OPTION (ORACA=YES); 

その後、ORACA内のフラグを設定することによって、適切なランタイム・オプションを選択する必要があります。

ORACAの内容

ORACAには、次のように、オプションの設定、システムの統計および高度な診断情報が保存されています。

  • SQL文のテキスト(テキストの保存時に指定できます)

  • エラーが発生したファイルの名称(サブルーチンの使用時に便利です)

  • ファイル内のエラーの位置

  • カーソル・キャッシュのエラーおよび統計情報

oraca.hの一部を次に示します。

/*
NAME
  ORACA : Oracle Communications Area.

  If the symbol ORACA_NONE is defined, then there will be no ORACA
  *variable*, although there will still be a struct defined.  This
  macro should not normally be defined in application code.

  If the symbol ORACA_INIT is defined, then the ORACA will be
  statically initialized. Although this is not necessary in order
  to use the ORACA, it is a good pgming practice not to have
  unitialized variables. However, some C compilers/operating systems
  don't allow automatic variables to be init'd in this manner. Therefore,
  if you are INCLUDE'ing the ORACA in a place where it would be
  an automatic AND your C compiler/operating system doesn't allow this style
  of initialization, then ORACA_INIT should be left undefined --
  all others can define ORACA_INIT if they wish.
*/
 
#ifndef  ORACA
#define  ORACA      1
 
struct    oraca
{
    char oracaid[8];   /* Reserved               */
    long oracabc;      /* Reserved               */
 
/*    Flags which are setable by User. */
 
   long  oracchf;      /* <> 0 if "check cur cache consistncy"*/
   long  oradbgf;      /* <> 0 if "do DEBUG mode checking"    */
   long  orahchf;      /* <> 0 if "do Heap consistency check" */
   long  orastxtf;     /* SQL stmt text flag            */
#define  ORASTFNON 0   /* = don't save text of SQL stmt       */
#define  ORASTFERR 1   /* = only save on SQLERROR         */
#define  ORASTFWRN 2   /* = only save on SQLWARNING/SQLERROR  */
#define  ORASTFANY 3      /* = always save             */
    struct
      {
  unsigned short orastxtl;
  char  orastxtc[70];
      } orastxt;         /* text of last SQL stmt          */
    struct
      {
  unsigned short orasfnml;
  char      orasfnmc[70];
      } orasfnm;        /* name of file containing SQL stmt    */
  long   oraslnr;        /* line nr-within-file of SQL stmt     */
  long   orahoc;         /* highest max open OraCurs requested  */
  long   oramoc;         /* max open OraCursors required         */
  long   oracoc;         /* current OraCursors open         */
  long   oranor;         /* nr of OraCursor re-assignments      */
  long   oranpr;         /* nr of parses               */
  long   oranex;         /* nr of executes            */
    };

#ifndef ORACA_NONE

#ifdef ORACA_STORAGE_CLASS
ORACA_STORAGE_CLASS struct oraca oraca
#else
struct oraca oraca
#endif
#ifdef ORACA_INIT
    =
    {
    {'O','R','A','C','A',' ',' ',' '},
    sizeof(struct oraca),
    0,0,0,0,
    {0,{0}},
    {0,{0}},
    0,
    0,0,0,0,0,0
    }
#endif
    ;

#endif

#endif
/* end oraca.h */

ランタイム・オプションの選択について

ORACAにはいくつかのオプション・フラグがあります。これらのフラグに0(ゼロ)以外の値を設定することで、次のことが可能になります。

  • SQL文のテキストの保存

  • DEBUG処理の有効化

  • カーソル・キャッシュの一貫性チェック(カーソル・キャッシュとは、カーソル管理に使用されるメモリーで継続的に更新される領域)

  • ヒープの一貫性チェック(ヒープは、動的変数のために予約されるメモリー領域)

  • カーソル統計情報の収集

次の説明はオプションを選択するときの参考になります。

ORACAの構造体

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

oracaid

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

oracabc

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

oracchf

マスターDEBUGフラグ(oradbgf)が設定されていると、このフラグによってカーソル・キャッシュの統計情報の収集と、各カーソル操作前のカーソル・キャッシュの一貫性チェックができます。

Oracleランタイム・ライブラリでは一貫性チェックが行われ、エラー・メッセージが発行されることがあります(エラー・メッセージについては、『Oracle Databaseエラー・メッセージ』を参照してください)。これらは、Oracleエラー・メッセージと同様にSQLCAに戻されます。

このフラグは次のいずれかを設定します。

  • キャッシュ一貫性チェックを使用禁止にします(デフォルト)。

  • キャッシュ一貫性チェックを使用可能にします。

oradbgf

このマスター・フラグを使用すると、DEBUGオプションをすべて選択できます。これには次の設定があります。

すべてのDEBUG処理を使用禁止にします(デフォルト)。

すべてのDEBUG処理を有効にします。

orahchf

マスターDEBUGフラグ(oradbgf)が設定されていると、プリコンパイラによって動的にメモリーが割り当てまたは解放されるたびに、Oracleランタイム・ライブラリでヒープの一貫性がチェックされます。これはメモリー障害を起こすプログラムの不具合を検出するのに役立ちます。

このフラグはCONNECTコマンドを発行する前に設定する必要があります。また、このフラグは一度設定すると解除できなくなります。つまり、設定後にこのフラグの変更要求があっても無視されます。これには次の設定があります。

  • ヒープ一貫性チェックを無効にします(デフォルト)。

  • ヒープ一貫性チェックを有効にします。

orastxtf

このフラグを使用すると、現行のSQL文のテキストを保存するタイミングを指定できます。これには次の設定があります。

  • SQL文のテキストを保存しません(デフォルト)。

  • SQLERRORのSQL文のテキストのみ保存します。

  • SQLERRORまたはSQLWARNINGのSQL文のテキストのみ保存します。

  • 常にSQL文のテキストを保存します。

SQL文のテキストは、orastxtという名前のORACA埋込み構造体に保存されます。

診断

ORACAは高度な診断情報を提供します。次の変数によってエラーの位置をすばやく特定できます。

orastxt

この埋込み構造体は、問題のあるSQL文を見つけるために使用します。Oracleで解析された最後のSQL文のテキストを保存できます。これには次の2つのコンポーネントが格納されています。

コンポーネント 説明

orastxtl

この整数コンポーネントにはカレントSQL文の長さが格納されます。

orastxtc

この文字列コンポーネントにはカレントSQL文のテキストが格納されます。先頭から最大70文字までのテキストが保存されます。文字列はヌル文字で終了しません。文字列を印刷するときは、oratxtl長さコンポーネントを使用します。

プリコンパイラによって解析された文(CONNECT、FETCHおよびCOMMITなど)は、ORACAには保存されません

orasfnm

この埋込み構造体は、カレントSQL文が含まれているファイルを識別します。このため、1つのアプリケーション用に複数のファイルをプリコンパイルするときにエラーを検出できます。これには次の2つのコンポーネントが格納されています。

コンポーネント 説明

orasfnml

この整数コンポーネントには、orasfnmcに保存されているファイル名の長さが格納されます。

orasfnmc

この文字列コンポーネントにはファイル名が格納されます。先頭から最大70文字が格納されます。

oraslnr

この整数コンポーネントはカレントSQL文がある行またはその付近の行を識別します。

カーソル・キャッシュ統計情報

マスターDEBUGフラグ(oradbgf)およびカーソル・キャッシュ・フラグ(oracchf)が設定されているときは、次の変数を使用してカーソル・キャッシュ統計情報を収集できます。これらの変数は、プログラムがCOMMITコマンドまたはROLLBACKコマンドを発行するたびに自動的に設定されます。

内部的には、CONNECTされているデータベース別にこの変数のセットがあります。ORACA内の現在の設定値は、最後にCOMMITまたはROLLBACKが行われたデータベースに関係します。

orahoc

この整数コンポーネントは、プログラムの実行中にMAXOPENCURSORSに設定された最大値を記録します。

oramoc

この整数コンポーネントには、プログラムの要求によってオープンされたOracleカーソルの最大数が記録されます。MAXOPENCURSORSに設定されている値が小さすぎて、その結果プリコンパイラによってカーソル・キャッシュが拡張されると、この数はorahocより大きくなることがあります。

oracoc

この整数コンポーネントは、プログラムの要求によってオープンされているOracleカーソルのカレント数を記録します。

oranor

この整数コンポーネントには、プログラムの要求によって再度割り当てられたカーソル・キャッシュの数が記録されます。この数値は、カーソル・キャッシュのスラッシングの程度を示すもので、できるだけ小さく保つ必要があります。

oranpr

この整数コンポーネントは、プログラムの要求によって解析されたSQL文の数を記録します。

oranex

この整数コンポーネントは、プログラムの要求によって実行されたSQL文の数を記録します。この数値のoranprに対する割合は、できるかぎり高く保ってください。つまり、不要な再解析は回避する必要があります。

ORACAの例

次のプログラムは部門番号の入力を要求し、その部内の各従業員の名前および給与を2つの表のどちらかに挿入してから、ORACAからの診断情報を表示します。このプログラムはoraca.pcとしてdemoディレクトリにあり、オンラインで利用できます。

/* oraca.pc
 * This sample program demonstrates how to
 * use the ORACA to determine various performance
 * parameters at runtime.
 */
#include <stdio.h> 
#include <string.h>
#include <sqlca.h>
#include <oraca.h> 

EXEC SQL BEGIN DECLARE SECTION;
char *userid = "SCOTT/TIGER"; 
char  emp_name[21];
int   dept_number; 
float salary; 
char SQLSTATE[6];
EXEC SQL END DECLARE SECTION;

void sql_error(); 

main() 
{ 
    char temp_buf[32];

    EXEC SQL WHENEVER SQLERROR DO sql_error("Oracle error");
    EXEC SQL CONNECT :userid; 
    
    EXEC ORACLE OPTION (ORACA=YES);

    oraca.oradbgf  = 1;             /* enable debug operations */ 
    oraca.oracchf  = 1;      /* gather cursor cache statistics */ 
    oraca.orastxtf = 3;       /* always save the SQL statement */ 

    printf("Enter department number: "); 
    gets(temp_buf);
    dept_number = atoi(temp_buf);

    
    EXEC SQL DECLARE emp_cursor CURSOR FOR 
      SELECT ename, sal + NVL(comm,0) AS sal_comm
        FROM emp 
        WHERE deptno = :dept_number
        ORDER BY sal_comm DESC;
    EXEC SQL OPEN emp_cursor; 
    EXEC SQL WHENEVER NOT FOUND DO sql_error("End of data");
    
    for (;;) 
    { 
        EXEC SQL FETCH emp_cursor INTO :emp_name, :salary; 
        printf("%.10s\n", emp_name);
        if (salary < 2500) 
            EXEC SQL INSERT INTO pay1 VALUES (:emp_name, :salary); 
        else 
            EXEC SQL INSERT INTO pay2 VALUES (:emp_name, :salary);    
    } 
} 

void 
sql_error(errmsg)
char *errmsg;
{ 
    char buf[6];

    strcpy(buf, SQLSTATE);
    EXEC SQL WHENEVER SQLERROR CONTINUE; 
    EXEC SQL COMMIT WORK RELEASE; 
    
    if (strncmp(errmsg, "Oracle error", 12) == 0)
        printf("\n%s, sqlstate is %s\n\n", errmsg, buf);
    else
        printf("\n%s\n\n", errmsg);

    printf("Last SQL statement: %.*s\n", 
    oraca.orastxt.orastxtl, oraca.orastxt.orastxtc); 
    printf("\nAt or near line number %d\n", oraca.oraslnr); 
    printf
("\nCursor Cache Statistics\n------------------------\n"); 
    printf
("Maximum value of MAXOPENCURSORS:    %d\n", oraca.orahoc); 
    printf
("Maximum open cursors required:      %d\n", oraca.oramoc); 
    printf
("Current number of open cursors:     %d\n", oraca.oracoc); 
    printf
("Number of cache reassignments:      %d\n", oraca.oranor); 
    printf
("Number of SQL statement parses:     %d\n", oraca.oranpr); 
    printf
("Number of SQL statement executions: %d\n", oraca.oranex); 
    exit(1); 
}