ヘッダーをスキップ
Oracle® Database Oracleプリコンパイラのためのプログラマーズ・ガイド
11g リリース2(11.2)
B61344-01
  目次
目次
索引へ
索引

前へ
前へ
 
次へ
次へ
 

A 新機能

この付録では、Oralceプリコンパイラ、リリース1.8の改良点と新機能について説明します。プロのソフトウェア開発者の実際的なニーズを満たすように設計されたこれらの機能は、効率的かつ信頼できるアプリケーションの作成に役立ちます。

インジケータ変数を使用しないNULLのフェッチ

Oracleプリコンパイラのリリース1.5、1.6および1.7では、インジケータ変数が関連付けられていないホスト変数にデータをFETCHするソース・ファイルの場合、実行時にホスト変数にNULLが戻されると、ORA-01405のメッセージが表示されます。リリース1.8では、MODE=ORACLEおよびDBMS=V7を指定するとき、UNSAFE_NULL=YESも指定すると、ORA-01405のメッセージが表示されなくなります。

Oracleデータベース用のアプリケーションを開発する場合、NULLが戻される可能性のあるホスト変数には、インジケータ変数を組み込むことをお薦めします。ただし、Oracleバージョン6からOracleデータベース・バージョン7へアプリケーションを移行する際には、UNSAFE_NULLオプションを使用すると、移行のプロセスが非常に容易になります。

詳細は、「UNSAFE_NULL」および「インジケータ変数の使用方法」を参照してください。

DBMS=V6の使用方法

DBMS=V6を指定してプリコンパイルしたアプリケーションは、Oracleバージョン6との完全な互換性が維持されます。Oracleデータベース・バージョン7にアップグレードするとき、DBMS=V6を指定してプリコンパイルすると、アプリケーションはORA-01405メッセージの影響を受けなくなります。

DBMS=V7およびMODE=ORACLEの使用方法

MODE=ORACLEおよびDBMS=V7を指定してプリコンパイルしたアプリケーションでは、実行時にインジケータ変数が関係付けられていないホスト変数にNULLが戻されると、ORA-01405エラーが発生します。これらのオプションを指定してOracleデータベース・バージョン7にアップグレードするときには、次の2つの方法のいずれかでアプリケーションを移行する必要があります。

  • 必要なインジケータ変数を組み込むようにソース・コードを変更

  • コマンドラインでUNSAFE_NULL=YESを指定

Oracleデータベース・バージョン7にアップグレード中で、プリコンパイル時にDBMS=V7を使用するとき、またはOracleバージョン6と異なるOracleデータベース・バージョン7の新機能を使用するとき、ほとんどの場合、ソース・ファイルに対する変更は最小限で済みます。ただし、アプリケーションでインジケータ変数が関連付けられていないホスト変数にNULL値をFETCHする可能性がある場合は、ORA-01405メッセージが表示されないようにUNSAFE_NULL=YESを指定し、ソース・ファイルに関連するインジケータ変数を追加しないでください。

関連のエラー・メッセージ

UNSAFE_NULLオプションに関連するプリコンパイル時のメッセージの詳細は、『Oracle Databaseエラー・メッセージ』を参照してください。

追加の配列挿入/選択構文

DB2プリコンパイラの配列INSERTおよび配列SELECT構文が、Oracleプリコンパイラでサポートされるようになりました。オプションのROWSET句およびROWSET STARTING AT句は、フェッチ方向(FIRST、PRIOR、NEXT、LAST、CURRENT、RELATIVEおよびABSOLUTE)で使用されます。新しいINSERT/SELECT構文の詳細は、『Pro*COBOLプログラマーズ・ガイド』および『Pro*C/C++プログラマーズ・ガイド』を参照してください。

SQL99構文のサポート

SQL規格により、規格に準拠するすべてのソフトウェア製品で、SQLアプリケーションを移植できます。Oracle機能は、ANSI/ISO SQL99規格(ANSI準拠の結合を含む)に準拠しています。Pro*Cobolでは、OracleデータベースでサポートされているすべてのSQL99機能がサポートされており、SELECT文、INSERT文、DELETE文およびUPDATE文と、DECLARE CURSOR文でのカーソル本体のSQL99構文がサポートされています。

実行計画の修正

Pro*C/C++またはPro*Cobol開発環境で使用されるSQLの実行計画を修正するには、プリコンパイル時にOracleのアウトライン機能を使用する必要があります。アウトラインは、SQL文と関連付けられた一連のオプティマイザのヒントとして実装されています。文に対するアウトラインの使用を有効にすると、Oracleでは格納されたヒントを自動的に検討し、それらのヒントに従って実行計画の生成を試みます。このようにして、異なる環境へのモジュールの統合やデプロイを行うときに、パフォーマンスに影響が及ばないようにすることができます。

Pro*C/C++およびPro*Cobolでアウトラインを作成するときには、次のSQL文を使用できます。

アウトライン・オプションが設定されると、プリコンパイラでは、正常にプリコンパイルが終了した時点でSQLファイルとLOGファイルの2つのファイルが生成されます。コマンドライン・オプションのoutlineおよびoutlnprefixが、アウトラインの生成を制御します。生成される各アウトラインの名前は一意です。アプリケーションで使用されるファイル名は一意であるため、この情報がアウトライン名の生成で使用されます。さらに、カテゴリ名も前に付けられます。


注意:

Oracleでは、アウトライン名に30バイトしか指定できません。この制限を超えると、プリコンパイラではエラーが発生します。アウトライン名の長さは、outlnprefixオプションを使用すれば制限できます。


参照:

  • 『Pro*COBOLプログラマーズ・ガイド』

  • 『Pro*C/C++プログラマーズ・ガイド』


暗黙的バッファ済挿入の使用方法

パフォーマンス向上のために、アプリケーション開発者は、埋込みSQL文内のホスト配列を参照できます。これにより、データベースへの1回のラウンドトリップで、SQL文の配列を実行できます。配列の実行によりパフォーマンスが大幅に向上するにもかかわらず、ANSI規格ではないという理由で、この機能を使用しない開発者もいます。たとえば、Oracleで配列実行を利用するために作成されたアプリケーションは、IBMのプリコンパイラではプリコンパイルできません。

回避策の1つは、バッファ済のINSERT文を使用することです。これにより、ANSI規格の埋込みSQL構文を保持しつつ、パフォーマンスを向上させることができます。

コマンドライン・オプションmax_row_insertは、INSERT文を実行する前にバッファされる行数を制御します。デフォルトはゼロで、機能は無効です。この機能を有効にするには、ゼロより大きい数を指定してください。


参照:

暗黙的バッファ挿入機能の使用方法の詳細は、次のマニュアルを参照してください。
  • 『Pro*COBOLプログラマーズ・ガイド』

  • 『Pro*C/C++プログラマーズ・ガイド』


動的SQL文のキャッシング

文のキャッシングとは、セッションごとに文のキャッシュを提供し管理する機能のことです。サーバーでは、文を再び解析することなく、カーソルがいつでも使用できるようになっていることを意味します。文のキャッシングは、プリコンパイラ・アプリケーションで有効にでき、動的SQL文に依存するすべてのアプリケーションのパフォーマンス向上に役立ちます。パフォーマンスの向上は、動的文を再利用する際の解析のオーバーヘッドをなくすことで達成されます。

このパフォーマンスの改善は、動的文のキャッシングが可能になる新しいコマンドライン・オプションstmt_cache(文のキャッシュ・サイズ用)を使用することで実現します。この新しいオプションを有効にすると、セッション作成時に文のキャッシュが作成されます。キャッシングは動的文に対してのみ適用され、静的文用のカーソル・キャッシュとこの機能は共存します。

コマンドライン・オプションのstmt_cacheには、0~65535の範囲の任意の値を指定できます。文のキャッシングは、デフォルトでは無効です(0の値)。stmt_cacheオプションは、アプリケーションで予想される数の個別の動的SQL文を保存するために設定できます。

例A-1 stmt_cacheオプションの使用方法

この例は、stmt_cacheオプションの使用方法を示しています。このプログラムでは、表に行を挿入し、ループでカーソルを使用して挿入した行を選択します。このプログラムのプリコンパイルにstmt_cacheオプションを使用すると、通常のプリコンパイルに比べてパフォーマンスが向上します。

/*
 *  stmtcache.pc
 *
 *  NOTE: 
 *  When this program is used to measure the performance with and without
 *  stmt_cache option, do the following changes in the program,
 *  1. Increase ROWSCNT to high value, say 10000.
 *  2. Remove all the print statements, usually which comsumes significant
 *     portion of the total program execution time.
 * 
 *  HINT: In Linux, gettimeofday() can be used to measure time. 
 */
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlca.h>
#include <oraca.h>
 
#define ROWSCNT 10
 
char    *username = "scott";
char    *password = "tiger";
 
/* Function prototypes */
void sql_error(char *msg);
void selectdata();
void insertdata();
 
int main()
{
  EXEC SQL WHENEVER SQLERROR DO sql_error("Oracle error");
 
  /* Connect using the default schema scott/tiger */
  EXEC SQL CONNECT :username IDENTIFIED BY :password;
 
  /* core functions to insert and select the data */
  insertdata();
  selectdata();
 
/* Rollback pll the changes and disconnect from Oracle. */
  EXEC SQL ROLLBACK WORK RELEASE;
 
  exit(0);
}
 
/*Insert the data for ROWSCNT items into tpc2sc01 */
void insertdata()
{
  varchar dynstmt[80];
  int i;
  varchar ename[10];
  float comm;
  char *str;
 
  /* Allocates temporary buffer */
  str = (char *)malloc (11 * sizeof(char));
 
  strcpy ((char *)dynstmt.arr,
          "INSERT INTO bonus (ename, comm) VALUES (:ename, :comm)");
  dynstmt.len = strlen(dynstmt.arr);
  EXEC SQL PREPARE S FROM :dynstmt;
 
  printf ("Inserts %d rows into bonus table using dynamic SQL statement\n",
          ROWSCNT);
  for (i=1; i<=ROWSCNT; i++)
  {
    sprintf (str, "EMP_%05d",i);
    strcpy (ename.arr, str);
    comm = i;
    ename.len = strlen (ename.arr);
    EXEC SQL EXECUTE S USING :ename, :comm;
  }
 
  free(str);
}
 
/* Select the data using the cursor */
void selectdata()
{
  varchar dynstmt[80];
  varchar ename[10];
  float comm;
  int i;
 
  strcpy((char *)dynstmt.arr,
         "SELECT ename, comm FROM bonus WHERE comm = :v1");
  dynstmt.len = (unsigned short)strlen((char *)dynstmt.arr);
 
  printf ("Fetches the inserted rows using using dynamic SQL statement\n\n");
  printf ("  ENAME      COMMISSION\n\n");
 
  for (i=1; i<=ROWSCNT; i++)
  {
    /* Do the prepare in the loop so that the advantage of stmt_caching 
       is visible*/
    EXEC SQL PREPARE S FROM :dynstmt;
 
    EXEC SQL DECLARE C CURSOR FOR S;
    EXEC SQL OPEN C USING :i;
 
    EXEC SQL WHENEVER NOT FOUND DO break;
 
    /* Loop until the NOT FOUND condition is detected. */
    for (;;)
    {
      EXEC SQL FETCH C INTO :ename, :comm;
      ename.arr[ename.len] = '\0';
      printf ("%10s    %7.2f\n", ename.arr, comm);
    }
    /* Close the cursor so that the reparsing is not required for stmt_cache */
    EXEC SQL CLOSE C;
  }
}
 
void sql_error(char *msg)
{
    printf("\n%s", msg);
    sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
    oraca.orastxt.orastxtc[oraca.orastxt.orastxtl] = '\0';
    oraca.orasfnm.orasfnmc[oraca.orasfnm.orasfnml] = '\0';
    printf("\n%s\n", sqlca.sqlerrm.sqlerrmc);
    printf("in \"%s...\"\n", oraca.orastxt.orastxtc);
    printf("on line %d of %s.\n\n", oraca.oraslnr,
       oraca.orasfnm.orasfnmc);
 
   /* Disable ORACLE error checking to avoid an infinite loop
    * should another error occur within this routine.
    */
    EXEC SQL WHENEVER SQLERROR CONTINUE;
 
    /* Release resources associated with the cursor. */
    EXEC SQL CLOSE C;
 
    /* Roll back any pending changes and disconnect from Oracle. */  
    EXEC SQL ROLLBACK WORK RELEASE;
    exit(1);
}

スクロール可能カーソル

スクロール可能なカーソルとは、OracleでSQL文を実行し、実行中に処理した情報を格納する作業領域です。カーソルを実行すると、問合せの結果が結果セットと呼ばれる一連の行に格納されます。結果セットは、順次または非順次のいずれでもフェッチできます。非順次の結果セットは、スクロール可能カーソルと呼ばれます。スクロール可能カーソルにより、ユーザーはデータベース結果セットの行に、前方、後方、無作為のいずれの方法でもアクセスできます。このスクロール可能カーソルを使用すれば、プログラムでは結果セットの任意の行をフェッチできます。スクロール可能カーソルの詳細は、『Pro*COBOLプログラマーズ・ガイド』を参照してください。

プラットフォーム・エンディアン・サポート

Oracleで格納されるユニコード・データ(UTF16)は、常にビッグエンディアン方式です。現在、クライアント・アプリケーションは様々なプラットフォーム上で実行されます。LinuxおよびWindowsではリトルエンディアン方式で表わされ、Solarisではビッグエンティアン方式で表わされます。UTF16データが挿入または選択されるとき、Pro*Cobolではサーバーとクライアント間でエンディアン方式を変換しません。これは、PIC N変数でのUTF16(UCS2)文字列の破損の原因になります。

PIC N変数でのプラットフォーム・エンディアン(LinuxおよびWindowsの場合はリトルエンディアン方式、Solarisの場合はビッグエンディアン方式)は、コマンドライン・オプションのpicn_endianを使用すれば維持できます。

新しいコマンドライン・オプション

picn_endian={BIG|OS}

picn_endian=bigの場合、PIC N変数は、キャラクタ・セットID AL16UTF16に関連付けられます。

picn_endian=osの場合、PIC N変数はキャラクタ・セットID UCS2に関連付けられます。

このオプションのデフォルト値は、現行の動作を維持するBIGです。このオプションは、NLS_NCHARがAL16UTF16でない場合は無視されます。

PIC N変数のキャラクタ・セットの方式は、既存のPro*Cobolコマンドライン・オプションを使用すれば設定できます。

charset_picn={nchar_charset|db_charset}

柔軟なB領域の長さ

Pro*CobolプログラムのB領域の長さは、書式がANSIに設定されている場合、72に制限されます。Cobolコンパイラでは、最大253までのB領域の長さをサポートできるようになりました。これにより、プログラマは72列より長い行を自由に入力できます。Pro*Cobolでは、Pro*Cobolアプリケーションが最大253までの長さのB領域がサポートされるようになりました。それには、

FORMAT=VARIABLE

オプションを使用します。