10 ANSI動的SQL

この章では、新しい方法4アプリケーションに使用するANSI動的SQL (SQL標準の指定どおりの動的SQL)のOracleでの実装を説明します。実装は、「Oracle動的SQL: 方法4」で説明する従来のOracle動的SQL方法4に拡張機能を加えたものです。Oracle方法4ではカーソル変数、グループ項目の表、DML RETURNING句およびLOBはサポートされませんが、ANSI方法4ではOracleの型がすべてサポートされます。

従来のOracle動的SQL方法4では記述子はユーザーのPro*COBOLプログラムで定義されますが、ANSI動的SQLでは記述子はOracle内部で管理されます。どちらの場合でも、方法4では、Pro*COBOLプログラムが様々な数のホスト変数を含むSQL文の受け入れまたは作成を行います。

この章の内容は、次のとおりです。

10.1 ANSI動的SQLの基礎

次のSQL文について考えます。

SELECT ename, empno FROM emp WHERE deptno = :deptno_data 

ANSI動的SQLを使用するステップは、次のとおりです。

  • 実行する文を格納する文字列などの変数を宣言します。

  • 入力変数および出力変数に記述子を割り当てます。

  • 文を準備します。

  • 入力記述子の入力を記述します。

  • 入力記述子を設定します(この例では1つの入力ホスト・バインド変数deptno_data)。

  • 動的カーソルを宣言およびオープンします。

  • 出力記述子(上の例の出力ホスト変数は、enameおよびempno)を設定します。

  • enameおよびempnoデータ・フィールドを各行から取り出すために、GET DESCRIPTORを使用してデータを繰り返しフェッチします。

  • 取り出したデータを処理します(出力など)。

  • 動的カーソルを閉じ、入力記述子および出力記述子への割当てを解除します。

10.1.1 プリコンパイラのオプション

通常、ANSI動的SQLを使用する場合はプリコンパイラのANSI規格に従ってコードを記述するため、マクロ・コマンドライン・オプションMODE=ANSIを使用します。MODE=ANSIを使用せずにこの方法を使用する場合は、マイクロ・コマンドライン・オプションDYNAMIC=ANSIによって機能を制御します。

マイクロ・プリコンパイラ・オプションDYNAMICをANSIに設定するか、マクロ・オプションMODEをANSIに設定します。これによって、DYNAMICのデフォルト値がANSIに設定されます。DYNAMICのもう1つの設定はORACLEです。マイクロ・オプションの詳細は、「マクロ・オプションおよびマイクロ・オプション」およびDYNAMICを参照してください。

ANSI型コードを使用するには、TYPE_CODEプリコンパイラ・マイクロ・オプションをANSIに設定するか、MODEマクロ・オプションをANSIに設定します。これによって、TYPE_CODEのデフォルト設定がANSIになります。TYPE_CODEANSIに設定するには、DYNAMICANSIに設定する必要があります。

ANSI SQL型のリストは、「ANSI SQLデータ型」を参照してください。データベース・プラットフォーム間での移植性があり、可能なかぎりANSIに準拠したアプリケーションを作成する場合は、プリコンパイラ・オプションTYPE_CODEをANSIに設定してANSI型を使用してください。

詳細は、MODEおよびTYPE_CODEを参照してください。

10.2 ANSI SQL文の概要

動的SQL文では、記述子領域は使用する前に割り当てます。

ALLOCATE DESCRIPTOR文の構文は次のとおりです。

     EXEC SQL ALLOCATE DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}
        [WITH MAX {:occurrences | numeric_literal}]
     END-EXEC.

グローバル記述子は、プログラム内の任意のモジュールで使用できます。ローカル記述子は、その記述子を割り当てたファイル内でのみアクセス可能です。デフォルトはローカルです。

記述子名desc_namは、ホスト変数です。かわりに文字列リテラルを使用することもできます。

occurrencesは、記述子に格納できるバインド変数または列の最大数です。デフォルトは100です。

記述子が必要なくなった場合は、割当てを解除してメモリーを節約します。

割当て解除文は次のとおりです。

     EXEC SQL DEALLOCATE DESCRIPTOR [GLOBAL | LOCAL]
        {:desc_nam | string_literal}
     END-EXEC.

準備済のSQL文に関する情報を取得するには、DESCRIBE文を使用します。DESCRIBE INPUTでは、準備済の動的文のバインド変数が記述されます。DESCRIBE OUTPUT (デフォルト)では、出力列の番号、型および長さが記述されます。単純化した構文は次のとおりです。

     EXEC SQL DESCRIBE [INPUT | OUTPUT] sql_statement 
        USING [SQL] DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}
     END-EXEC.

SQL文に入力値および出力値がある場合は、入力値および出力値に1つずつ記述子を割り当てる必要があります。入力値がない次の例のような場合があります。

SELECT ename, empno FROM emp 

この場合、入力記述子は必要ありません。

SELECT文のINSERTS、UPDATES、DELETESおよびWHERE句の入力値を指定するには、SET DESCRIPTOR文を使用します。入力記述子にDESCRIBEを行っていないときは、SET DESCRIPTORを使用して(COUNTに格納する)入力バインド変数の数を設定します。

     EXEC SQL SET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} 
        COUNT = {:kount | numeric_literal} 
     END-EXEC.

kountには、ホスト変数または数値リテラル(5など)を指定できます。SET DESCRIPTOR文を各ホスト変数に使用して、少なくとも変数のデータ値は割り当てる必要があります。

     EXEC SQL SET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}
        VALUE item_number DATA = :hv3
     END-EXEC.

また、次のように入力ホスト変数の型および長さを設定することもできます。

注意: 型および長さの設定をSET DESCRIPTOR文で明示的に、またはDESCRIBE OUTPUTを実行して暗黙的に行わなかった場合、TYPE_CODE=ORACLEの場合は、ホスト変数自体から導出された型および長さの値がプリコンパイラで使用されます。TYPE_CODE=ANSIのときは、表10-1の値を使用して型を設定する必要があります。また、ANSIのデフォルトの長さがホスト変数のデフォルトの長さと一致しない場合があるので、長さも設定してください。

     EXEC SQL SET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}
        VALUE item_number TYPE = :hv1, LENGTH = :hv2, DATA = :hv3
     END-EXEC.

hv1hv2およびhv3 などの識別子は、ホスト変数から値を供給する必要があることをユーザーが忘れないようにするために使用します。item_numberは、入力変数のSQL文内での位置を表します。ホスト変数であることも、整数であることもあります。

TYPE_CODEをANSIに設定した場合は、次の表の型コードからTYPEを選択します。

表10-1 ANSI SQLデータ型

データ型 型コード

CHARACTER

1

CHARACTER VARYING

12

DATE

9

DECIMAL

3

DOUBLE PRECISION

8

FLOAT

6

INTEGER

4

NUMERIC

2

REAL

7

SMALLINT

5

Oracle型コードは表11-2を参照してください。ANSIデータ型が表になく、TYPE_CODE = ANSIである場合は、Oracleコードの負の値を使用してください。

DATAは、入力されるホスト変数値です。

インジケータ、精度、位取りなど、その他の入力値を設定することもできます。詳細は、「SET_DESCRIPTOR」の使用できる記述子項目名のリストを参照してください。

SET DESCRIPTOR文の数値は、PIC S9(9) COMP またはPIC S9(4) COMPのいずれかで宣言する必要があります。ただし、インジケータおよび戻される長さの値は、PIC S9(4) COMPとして宣言する必要があります。

次の例では、empnoを取得する場合、empnoは動的SQL文の2番目の出力ホスト変数であるため、値をVALUE = 2に設定します。ホスト変数EMPNO-TYPは、3(Oracleタイプの整数値)に設定します。ホスト整数の長さを表すEMPNO-LENは、4に設定します。この値はホスト変数のサイズです。DATAはホスト変数EMPNO-DATAと等しくなります。この変数は値をデータベース表から受け取ります。コード例は、次のようになります。

 ... 
 01  DYN-STATEMENT PIC X(58)
     VALUE "SELECT ename, empno FROM emp WHERE deptno =:deptno_number".
 01  EMPNO-DATA PIC S9(9) COMP.
 01  EMPNO-TYP  PIC S9(9) COMP   VALUE 3.
 01  EMPNO-LEN  PIC S9(9) COMP   VALUE 4.
 ...
     EXEC SQL SET DESCRIPTOR 'out' VALUE 2  TYPE=:EMPNO-TYP, LENGTH=:EMPNO-LEN,
        DATA=:EMPNO-DATA END-EXEC.
 

入力値を設定後に、入力記述子を使用して文を実行またはオープンします。文中に出力値がある場合、FETCHを行う前に出力値を設定してください。DESCRIBE OUTPUTを実行した場合、ホスト変数の実際の型および長さをリセットしなければならないことがあります。DESCRIBEの実行により、ホスト変数の外部型および長さとは異なる内部型および長さが生成されるためです。

出力記述子をFETCHした後、戻されたデータにアクセスするには、GET DESCRIPTORを使用します。簡略化された構文は次のとおりです。構文の詳細は、この章の後半部分を参照してください。

     EXEC SQL GET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}
        VALUE item_number 
        :hv1 = DATA, :hv2 = INDICATOR, :hv3 = RETURNED_LENGTH
     END-EXEC.

desc_namおよびitem_numberには、リテラルまたはホスト変数を指定できます。記述子名には、リテラル(outなど)を指定できます。項目番号には、数値リテラル(2など)を指定できます。

hv1、hv2およびhv3は、それぞれホスト変数です。ここにはホスト変数を指定する必要があり、リテラルは指定できません。例では、戻されるデータを3つのみ示しています。戻されたデータから取得できるすべての項目の一覧については、表10-4を参照してください。

数値には、プラットフォーム依存の上限がnであるPIC S9(n) COMPを使用するか、またはPIC S9(9) COMPPIC S9(4) COMPを使用します。ただし、標識変数および戻される長さの変数はPIC S9(4) COMPであることが必要です。

関連項目

10.3 サンプル・コード

次の例は、ANSI動的SQLの使用方法を示しています。ここでは入力記述子inおよび出力記述子outを割り当ててSELECT文を実行します。入力値はSET DESCRIPTOR文を介して設定します。カーソルはオープンおよびフェッチされ、結果の出力値はGET DESCRIPTOR文を介して取得されます。

 ... 
 01  DYN-STATEMENT PIC X(58)
     VALUE "SELECT ENAME, EMPNO FROM EMP WHERE DEPTNO =:DEPTNO-DAT".
 01  EMPNO-DAT  PIC S9(9) COMP.
 01  EMPNO-TYP  PIC S9(9) COMP   VALUE 3.
 01  EMPNO-LEN  PIC S9(9) COMP   VALUE 4.
 01  DEPTNO-TYP PIC S9(9) COMP   VALUE 3.
 01  DEPTNO-LEN PIC S9(9) COMP   VALUE 4.
 01  DEPTNO-DAT PIC S9(9) COMP   VALUE 10.
 01  ENAME-TYP  PIC S9(9) COMP   VALUE 3.
 01  ENAME-LEN  PIC S9(9) COMP   VALUE 30.
 01  ENAME-DAT  PIC X(30).
 01  SQLCODE PIC S9(9)    COMP   VALUE 0.
 ...
* Place preliminary code, including connection, here
...
     EXEC SQL ALLOCATE DESCRIPTOR 'in' END-EXEC.
     EXEC SQL ALLOCATE DESCRIPTOR 'out' END-EXEC.
     EXEC SQL PREPARE s FROM :DYN-STATEMENT END-EXEC.
     EXEC SQL DESCRIBE INPUT s USING DESCRIPTOR 'in' END-EXEC.
     EXEC SQL SET DESCRIPTOR 'in' VALUE 1 TYPE=:DEPTNO-TYP,
        LENGTH=:DEPTNO-LEN, DATA=:DEPTNO-DAT END-EXEC.
     EXEC SQL DECLARE c CURSOR FOR s END-EXEC.
     EXEC SQL OPEN c USING DESCRIPTOR 'in' END-EXEC.
     EXEC SQL DESCRIBE OUTPUT s USING DESCRIPTOR 'out' END-EXEC.
     EXEC SQL SET DESCRIPTOR 'out' VALUE 1 TYPE=:ENAME-TYP, 
        LENGTH=:ENAME-LEN, DATA=:ENAME-DAT END-EXEC.
     EXEC SQL SET DESCRIPTOR 'out' VALUE 2 TYPE=:EMPNO-TYP, 
        LENGTH=:EMPNO-LEN, DATA=:EMPNO-DAT END-EXEC.

     EXEC SQL WHENEVER NOT FOUND GOTO BREAK END-EXEC.
 LOOP.
     IF SQLCODE NOT = 0
        GOTO BREAK.
     EXEC SQL FETCH c INTO DESCRIPTOR 'out' END-EXEC.
     EXEC SQL GET DESCRIPTOR 'OUT' VALUE 1 :ENAME-DAT = DATA END-EXEC.
     EXEC SQL GET DESCRIPTOR 'OUT' VALUE 2 :EMPNO-DAT = DATA END-EXEC.
     DISPLAY "ENAME = " WITH NO ADVANCING
     DISPLAY ENAME-DAT  WITH NO ADVANCING
     DISPLAY "EMPNO = " WITH NO ADVANCING
     DISPLAY EMPNO-DAT.
     GOTO LOOP.
 BREAK:
     EXEC SQL CLOSE c END-EXEC.
     EXEC SQL DEALLOCATE DESCRIPTOR 'in' END-EXEC.
     EXEC SQL DEALLOCATE DESCRIPTOR 'out' END-EXEC.

10.4 Oracle拡張機能

この項では、次の拡張機能を説明します。

  • SET文のデータ項目の参照セマンティクス。

  • バルク操作のための配列。

  • オブジェクト型、NCHAR列およびLOBのサポート。

10.4.1 参照セマンティクス

ANSI規格では、構文が指定されています。パフォーマンス向上のために、Oracleではこの規格を拡張して参照セマンティクスを導入しています。

値構文では、ホスト変数データのコピーを作成します。参照セマンティクスでは、ホスト変数のアドレスを使用し、コピーは行いません。そのため、参照セマンティクスを使用すると、大量データ処理のパフォーマンスが向上します。

フェッチの速度向上には、データ句の前にREFキーワードを使用します。

     EXEC SQL SET DESCRIPTOR 'out' VALUE 1 TYPE=:ENAME-TYP,
        LENGTH=:ENAME-LEN, REF DATA=:ENAME-DAT END-EXEC.
     EXEC SQL DESCRIPTOR 'out' VALUE 2 TYPE=:EMPNO-TYP,
        LENGTH=:EMPNO-LEN, REF DATA=:EMPNO-DAT END-EXEC.

これにより、取り出された結果がホスト変数に渡されます。GET文は必要ありません。FETCHが実行されるたびに、取り出されたデータは、ename_dataおよびempno_dataに直接書き込まれます。

次のコード例に示すように、REFキーワードが使用できるのは、DATA、INDICATORおよびRETURNED_LENGTH項目(フェッチする行によって変わる可能性があります)の前に限られます

 01   INDI       PIC S9(4) COMP.
 01   RETRN-LEN  PIC S9(9) COMP.
 ...
      EXEC SQL SET DESCRIPTOR 'out' VALUE 1 TYPE=:ENAME-TYP,
         LENGTH=:ENAME-LEN, REF DATA=:ENAME-DAT,
         REF INDICATOR=:INDI, REF RETURNED_LENGTH =:RETRN-LEN END-EXEC.

フェッチするたびに、enameフィールドの実際に取り出された長さがRETRN-LENに送られます。これは、CHARまたはVARCHAR2データの場合に便利です。

ENAME-LENには取り出された長さは渡されません。これは、FETCH文によって変更されません。データの行をフェッチする前に列の最大幅を調べるには、GET文の前にDESCRIBEを使用します。

REFキーワードは、SELECT以外のSQL文の処理速度向上のためにも使用します。参照セマンティクスでは、記述子領域にコピーされた値ではなくホスト変数が使用されることに注意してください。SQL文を実行する時点でのホスト変数データが使用されるのであって、SETの時点でのデータではありません。次はその例です。

 ...
     MOVE 1 to VAL.
 ...
     EXEC SQL SET DESCRIPTOR 'value' VALUE 1 DATA = :VAL END-EXEC.
     EXEC SQL SET DESCRIPTOR 'reference' VALUE 1 REF DATA = :VAL END-EXEC.
     MOVE 2 to VAL.
* Will use  VAL = 1
     EXEC SQL EXECUTE s USING  DESCRIPTOR 'value' END-EXEC.
*Will use VAL = 2
     EXEC SQL EXECUTE s USING DESCRIPTOR 'reference' END-EXEC.

この処理の違いの詳細は、「SET_DESCRIPTOR」を参照してください。

関連項目

10.4.2 バルク操作での表の使用方法

OracleでのANSI動的SQLの実装では、SQL標準の動的SQLを拡張したバルク操作を提供しています。バルク操作を行うには、処理する入力データ量または行数を指定するために、FOR句で配列サイズを指定します。

FOR句は、ALLOCATE文で最大データ量または最大行数の指定に使用します。最大配列サイズ100を指定するには、次のように記述します。

     EXEC SQL FOR 100 ALLOCATE DESCRIPTOR 'out' END-EXEC.

または

     MOVE 100 TO INT-ARR-SIZE.
     EXEC SQL FOR :INT-ARR-SIZE ALLOCATE DESCRIPTOR 'out' END-EXEC.

FOR句は、記述子にアクセスする後続の文で使用されます。次に示すように、出力記述子では、ALLOCATE文で指定した配列サイズと等しいか、それよりも小さい配列サイズをFETCH文に割り当てる必要があります。

     EXEC SQL FOR 20 FETCH c1 USING DESCRIPTOR 'out' END-EXEC.

後続の、同じ記述子のDATA、INDICATORまたはRETURNED_LENGTH値を取得するGET文では、FETCH文と同じ配列サイズを指定する必要があります。

 01  VAL-DATA   OCCURS 20 TIMES  PIC S9(9) COMP.
 01  VAL-INDI   OCCURS 20 TIMES  PIC S9(4) COMP.
...
     EXEC SQL FOR 20 GET DESCRIPTOR 'out' VALUE 1 :VAL-DATA = DATA,
       :VAL-INDI = INDICATOR 
     END-EXEC.

ただし、LENGTH、TYPE、COUNTなど、行によって変化しない項目を参照するGET文では、FOR句は使用しないでください

 01  CNT  PIC S9(9) COMP.
 01  LEN  PIC S9(9) COMP.
...
     EXEC SQL GET DESCRIPTOR 'out'   :CNT = COUNT END-EXEC.
     EXEC SQL GET DESCRIPTOR 'out' VALUE 1 :LEN = LENGTH END-EXEC.

これは、参照セマンティクスを使用したSET文でも同じです。FETCHの前にあり、DATA、INDICATORまたはRETURNED_LENGTHに対する参照セマンティクスを使用したSET文には、FETCHと同じ配列サイズを指定する必要があります。

 ... 
 01  REF-DATA   OCCURS 20 TIMES  PIC S9(9) COMP.
 01  REF-INDI   OCCURS 20 TIMES  PIC S9(4) COMP.
...
     EXEC SQL FOR 20 SET DESCRIPTOR 'out' VALUE 1 REF DATA = :REF-DATA,
        REF INDICATOR = :REF-INDI END-EXEC.

同様に、行のバッチの挿入など、入力に使用する記述子でも、ALLOCATE文で使用した配列サイズと等しいか、それよりも小さいサイズの配列サイズをEXECUTEまたはOPEN文に使用する必要があります。値および参照セマンティクスのどちらも、DATA、INDICATORまたはRETURNED_LENGTHにアクセスするSET文では、EXECUTE文と同じ配列サイズを使用する必要があります。

FOR句は、DEALLOCATEまたはPREPARE文では使用しません。

次のコード・サンプルに、出力記述子のないバルク操作の例を示します(出力はなく、表empに挿入する入力のみあります)。CNTの値は2です(INSERT文にENAMEおよびEMPNOの2つのホスト変数があることを示します)。データ表ENAME-TABLEには、TomDickおよびHarryの順で3つの文字列が保持されています。彼らの雇用者番号を表EMPNO-TABLEに格納します。インジケータ表ENAME-INDには2つ目の要素に-1の値を設定しているため、DickではなくNULLが挿入されます。

 01  DYN-STATEMENT  PIC X(240) value 
         "INSERT INTO EMP(ENAME, EMPNO) VALUES (:ENAME,:EMPNO)". 
 01  ARRAY-SIZE PIC S9(9) COMP   VALUE 3. 
 01  ENAME-VALUES. 
      05 FILLER PIC X(6)   VALUE "Tom   ". 
      05 FILLER PIC X(6)   VALUE "Dick  ". 
      05 FILLER PIC X(6)   VALUE "Harry ". 
 01  ENAME-TABLE REDEFINES ENAME-VALUES. 
      05 ENAME  PIC X(6)OCCURS 3 TIMES. 
 01  ENAME-IND  PIC S9(4) COMPOCCURS 3 TIMES. 
 01  ENAME-LEN  PIC S9(9) COMP   VALUE   6. 
 01  ENAME-TYP  PIC S9(9) COMP   VALUE  96. 
 01  EMPNO-VALUES. 
      05 FILLER PIC S9(9) COMP   VALUE 8001. 
      05 FILLER PIC S9(9) COMP   VALUE 8002. 
      05 FILLER PIC S9(9) COMP   VALUE 8003. 
 01  EMPNO-TABLE REDEFINES EMPNO-VALUES. 
      05 EMPNO  PIC S9(9) DISPLAY SIGN LEADING  OCCURS 3 TIMES. 
 01  EMPNO-LEN  PIC S9(9) COMP   VALUE   4. 
 01  EMPNO-TYP  PIC S9(9) COMP   VALUE   3. 
 01  CNT        PIC S9(9) COMP   VALUE   2. 
........ 
     EXEC SQL FOR :ARRAY-SIZE ALLOCATE DESCRIPTOR 'in' END-EXEC.  
     EXEC SQL PREPARE S FROM :DYN-STATEMENT  END-EXEC. 
     MOVE 0 TO ENAME-IND(1). 
     MOVE -1 TO ENAME-IND(2). 
     MOVE 0 TO ENAME-IND(3). 
     EXEC SQL SET DESCRIPTOR 'in' COUNT = :CNT END-EXEC. 
     EXEC SQL SET DESCRIPTOR 'in' VALUE 1  
        TYPE = :ENAME-TYP, LENGTH =:ENAME-LEN 
     END-EXEC. 
     EXEC SQL FOR :ARRAY-SIZE  SET DESCRIPTOR 'in' VALUE 1 
        DATA = :ENAME, INDICATOR = :ENAME-IND  
     END-EXEC. 
     EXEC SQL SET DESCRIPTOR 'in' VALUE 2  
        TYPE = :EMPNO-TYP, LENGTH =:EMPNO-LEN 
     END-EXEC. 
     EXEC SQL FOR :ARRAY-SIZE  SET DESCRIPTOR 'in' VALUE 2 
        DATA = :EMPNO  
     END-EXEC. 
     EXEC SQL FOR :ARRAY-SIZE EXECUTE S  
        USING DESCRIPTOR 'in' END-EXEC. 
  ...

この例のコードによって、次の値が表に挿入されます。

      EMPNO   ENAME 
      8001    Tom        
      8002            
      8003    Harry      

制限および注意の詳細は、「FOR句」を参照してください。

関連項目

10.5 ANSI動的SQLのプリコンパイラ・オプション

マクロ・オプションMODE (「MODE」を参照)では、ANSI互換特性を設定し、いくつかの機能を制御します。値にはANSIまたはORACLEを設定できます。個々の機能には、MODE設定に優先するマイクロ・オプションがあります。

プリコンパイラ・マイクロ・オプションDYNAMICでは、動的SQLの記述子の動作を指定します。プリコンパイラ・マイクロ・オプションTYPE_CODEでは、ANSIとOracleのどちらのデータ型コードを使用するかを指定します。

マクロ・オプションMODEをANSIに設定すると、マイクロ・オプションDYNAMICは自動的にANSIになります。MODEをORACLEに設定すると、DYNAMICはORACLEになります。

DYNAMICおよびTYPE_CODEはインラインでは使用できません。

次の表に、DYNAMIC設定による様々な機能への影響を示します。

表10-2 DYNAMICオプションの設定

機能 DYNAMIC=ANSI DYNAMIC=ORACLE

記述子の作成。

ALLOCATE文を使用する必要があります。

Oracle形式の記述子を使用する必要があります。

記述子の破壊。

DEALLOCATE文を使用できます。

該当なし

データの取得。

FETCH文およびGET文のどちらも使用できます。

FETCH文のみ使用できます。

入力データの設定。

DESCRIBE INPUT文を使用できます。SET文を使用する必要があります。

コードに記述子値を設定する必要があります。DESCRIBE BIND VARIABLES文を使用する必要があります。

記述子の表現。

引用符付きのリテラル、または記述子名を含むホスト識別子。

ホスト変数、SQLDAを指すポインタ。

利用可能なデータ型。

BITを除くすべてのANSI型、およびすべてのOracle型。

オブジェクト、LOBおよびカーソル変数を除くOracle型。

マイクロ・オプションTYPE_CODEは、プリコンパイラによってマクロ・オプションMODEと同じ値に設定されます。DYNAMICがANSIの場合、TYPE_CODEはANSI以外には設定できません。

TYPE_CODEの設定に対応する機能を次の表に示します。

表10-3 TYPE_CODEオプションの設定

機能 TYPE_CODE=ANSI TYPE_CODE=ORACLE

動的SQLからの入出力に使用するデータ型コード番号。

ANSI型があるときはANSIコード番号を使用します。ない場合はOracleコード番号の負の値を使用します。

DYNAMIC=ANSIのときのみ有効です。

Oracleコード番号を使用します。

DYNAMICの設定に関係なく使用できます。

関連項目

10.6 動的SQL文の構文

次の文の詳細は、「埋込みSQL文およびプリコンパイラ・ディレクティブ」のアルファベット順のリストを参照してください。

10.6.1 ALLOCATE DESCRIPTOR

この文はANSI動的SQLでのみ使用できます。

用途

この文は、SQL記述子領域を割り当てるために使用します。記述子、記述子のホスト・バインド項目の出現の最大数および配列サイズを指定します。

構文

     EXEC SQL [FOR [:]array_size] ALLOCATE DESCRIPTOR [GLOBAL | LOCAL]
        {:desc_nam | string_literal} [WITH MAX occurrences]
     END-EXEC.
10.6.1.1 変数

ALLOCATE記述子では様々な変数が使用できます。ALLOCATE記述子が使用できる変数にはarray_size、desc_nam、occurrencesなどがあります。

array_size

オプションのarray_size句(Oracle拡張機能)では表の処理をサポートしています。表の処理に記述子を使用できることをプリコンパイラに示します。

 GLOBAL | LOCAL

デフォルトでは、オプション句のスコープはLOCALに設定されています。ローカル記述子は、その記述子を割り当てたファイル内でのみアクセス可能です。グローバル記述子は、コンパイル・ユニット内のどのモジュールでも使用できます。

desc_nam

desc_nam変数は、モジュールで一意である必要があるローカル記述子を定義します。前回の割当てを解除せずに記述子を割り当てた場合は、ランタイム・エラーが生成されます。グローバル記述子は、アプリケーション全体で一意にしてください。そうでない場合はランタイム・エラーが発生します。

occurrences

オプションのoccurrences句は、記述子で使用可能なホスト変数の最大数です。occurrences変数は0から64Kの整定数である必要があります。それ以外の場合はエラーが戻されます。デフォルトは、100です。これらの規則に違反するとプリコンパイラ・エラーが戻されます。

10.6.1.2
     EXEC SQL ALLOCATE DESCRIPTOR 'SELDES' WITH MAX 50 END-EXEC.

     EXEC SQL FOR :BATCH ALLOCATE DESCRIPTOR GLOBAL :BINDDES WITH MAX 25
        END-EXEC.

10.6.2 DEALLOCATE DESCRIPTOR

用途

メモリーを解放するには、割当て解除文を使用します。この文は、事前に割り当てたSQL記述子領域を解除します。

構文

     EXEC SQL DEALLOCATE DESCRIPTOR [GLOBAL | LOCAL] 
        {:desc_nam | string_literal}
     END-EXEC.

変数

desc_nam

割当て解除記述子が使用できる唯一の変数がdesc_nam (記述子名)です。同じ名前およびスコープの記述子が割り当てられていない場合、または割り当てられ、すでに解除されている場合は、ランタイム・エラーが発生します。

     EXEC SQL DEALLOCATE DESCRIPTOR GLOBAL 'SELDES' END-EXEC.

     EXEC SQL DEALLOCATE DESCRIPTOR :BINDDES END-EXEC.

10.6.3 GET DESCRIPTOR

用途

この文は、SQL記述子領域からの情報の取得に使用します。

構文

     EXEC SQL [FOR [:]array_size] GET DESCRIPTOR [GLOBAL | LOCAL]
        {:desc_nam | string_literal}
        {:hv0  = COUNT | VALUE item_number :hv1 = item_name1 
        [{, :hvN = item_nameN }]}
     END-EXEC.

変数

array_size

FOR array_size変数は、オプションのOracle拡張機能です。 FOR array_sizeは、FETCH文のarray_sizeフィールドと等しいことが必要です。

desc_nam

記述子名。

GLOBAL | LOCAL

GLOBALは、すべてのプログラム・ファイルで記述子名が認識されることを示します。LOCALは、記述子名を割り当てたファイル内でのみ記述子名が認識されることを示します。LOCALがデフォルトです。

COUNT

バインド変数の合計数。

VALUE item_number

SQL文内での項目の位置。item_numberには変数または定数を指定できます。item_numberの値がCOUNTより大きい場合、「データが見つかりません。」という条件が戻されます。item_numberには0より大きい値を指定する必要があります。

hv1 .. hvN

値の転送先のホスト変数。

item_name1 .. item_nameN

ホスト変数に対応付けられた記述子項目名。使用できるANSI記述子項目名を次の表に示します。

表10-4 記述子項目名の定義

記述子項目名 意味

TYPE

ANSI型コードは表10-1を参照してください。Oracle型コードは表11-2を参照してください。ANSIデータ型が表になく、TYPE_CODE = ANSIである場合は、Oracleコードの負の値を使用してください。

LENGTH

列内のデータの長さ。NCHARは文字単位、それ以外はバイト単位です。DESCRIBE OUTPUTによって設定されます。

OCTET_LENGTH

バイト単位でのデータの長さ。

RETURNED_LENGTH

FETCH後の実際のデータ長。固定長キャラクタ・タイプについては未定義になります。

RETURNED_OCTET_LENGTH

戻されたデータのバイト単位での長さ。

PRECISION

桁数。

SCALE

真数値型での小数点の右側の桁数。

NULLABLE

1のときは、列にNULL値を使用できます。0のときは、列にNULL値は使用できません。

INDICATOR

対応付けられたインジケータ値。

DATA

データの値。

NAME

列の名前。

CHARACTER_SET_NAME

列のキャラクタ・セット。

次の表に、記述子項目名のOracle拡張機能を示します。

表10-5 記述子項目名の定義のOracle拡張機能

記述子項目名 意味

NATIONAL_CHARACTER

2はNCHARまたはNVARCHAR2を示します。1の場合は文字です。0の場合は文字以外の値です。

INTERNAL_LENGTH

内部でのバイト単位の長さ。

使用上の注意

FOR句は、DATA、INDICATORおよびRETURNED_LENGTH項目のみを含むGET DESCRIPTOR文で使用してください。

内部型は、DESCRIBE OUTPUT文によって設定されます。入力および出力のどちらでも、ホスト変数の外部型に使用する型を設定する必要があります。TYPEは、OracleコードまたはANSIコード(表10-1)です。ANSI型が表にはない場合は、Oracle型の負の値が戻されます。

LENGTHには、列の長さが格納され、固定幅の各国語キャラクタ・セットが設定されたフィールドでは文字単位になります。それ以外のキャラクタ列ではバイト単位になります。LENGTHはDESCRIBE OUTPUTによって設定されます。

RETURNED_LENGTHは、FETCH文によって設定される実際のデータ長です。LENGTHと同様にバイト単位または文字単位になります。フィールドOCTET_LENGTHおよびRETURNED_OCTET_LENGTHは、バイト単位の長さです。

NULLABLE = 1は、列にNULLを使用できることを示します。NULLABLE = 0は、列にNULLを使用できないことを示します。

CHARACTER_SET_NAMEは、キャラクタ列の場合にのみ意味があります。他の型では未定義になります。DESCRIBE OUTPUT文によって値が設定されます。

DATAおよびINDICATORは、その列のデータ値およびインジケータ・ステータスです。データがNULLでインジケータが要求されなかった場合は、実行時にエラーが発生します(DATA EXCEPTION, NULL VALUE, NO INDICATOR PARAMETER)。

Oracle固有の記述子項目名

列がNCHARまたはNVARCHAR2列の場合は、NATIONAL_CHARACTER = 2になります。列がキャラクタ(ただし、各国語キャラクタではない)列の場合、項目は1に設定されます。キャラクタ以外の列の場合、DESCRIBE OUTPUTの実行後にこの項目は0に設定されます。

INTERNAL_LENGTHは、Oracle動的方法4との互換性があるため、Oracle記述子領域の長さメンバーと同じ値に設定されます。この項目にはOracle記述子領域の長さメンバーと同じ値が設定されています。「Oracle動的SQL: 方法4」を参照してください。

     EXEC SQL GET DESCRIPTOR :BINDDES :COUNT = COUNT END-EXEC.

     EXEC SQL GET DESCRIPTOR 'SELDES' VALUE 1 :TYP = TYPE, :LEN = LENGTH
        END-EXEC.

     EXEC SQL FOR :BATCH GET DESCRIPTOR LOCAL 'SELDES'
        VALUE :SEL-ITEM-NO :IND = INDICATOR, :DAT = DATA END-EXEC. 

10.6.4 SET DESCRIPTOR

用途

この文は、ホスト変数からの記述子領域の情報を設定するために使用します。SET DESCRIPTOR文では、項目名のホスト変数のみサポートされます。

構文

     EXEC SQL [FOR [:]array_size] SET DESCRIPTOR [GLOBAL | LOCAL] 
        {:desc_nam | string_literal} 
        {COUNT = :hv0 | VALUE item_number
        [REF] item_name1 = :hv1 
        [{, [REF] item_nameN = :hvN}]}
     END-EXEC.

変数

array_size

このOracleオプション句で配列を使用できるのは、記述子項目DATA、INDICATORおよびRETURNED_LENGTHの設定時のみです。FOR句を含むSET DESCRIPTORでは他の項目を使用できません。ホスト変数表サイズはすべて一致している必要があります。FETCH文で使用するのと同じ配列サイズをSET文で使用してください。

desc_nam

記述子名。ALLOCATE DESCRIPTORでの規則が適用されます。

COUNT

バインド(入力)変数または定義(出力)変数の数。

VALUE item_number

動的SQL文でのホスト変数の位置。

hv1 .. hvN

設定するホスト変数(定数ではありません)。

item_name1 .. item_nameN

GET DESCRIPTOR構文(「GET DESCRIPTOR」を参照)と同様に、item_nameに次の値を指定できます。

表10-6 SET DESCRIPTORの記述子項目名

記述子項目名 意味

TYPE

ANSI型コードは表10-1を参照してください。Oracle型コードは表11-2を参照してください。ANSI型が表にはなく、TYPE_CODE = ANSIである場合は、Oracle型コードの負の値を使用してください。

LENGTH

列内のデータの最大長。

PRECISION

桁数。

SCALE

真数値型での小数点の右側のバイト数。

INDICATOR

対応付けられたインジケータ値。参照セマンティクスのために設定します。

DATA

設定するデータの値。参照セマンティクスのために設定します。

CHARACTER_SET_NAME

列のキャラクタ・セット。

次の表に、記述子項目名のOracle拡張機能を示します。

表10-7 SET DESCRIPTORの記述子項目名の拡張機能

記述子項目名 意味

RETURNED_LENGTH

FETCH後に戻される長さ。参照セマンティクスを使用する場合に設定します。

NATIONAL_CHARACTER

入力ホスト変数がNCHARまたはNVARCHAR2型のときは、2に設定します。

使用上の注意

参照セマンティクスは、パフォーマンス向上のために使用する別のオプションのOracle拡張機能です。記述子項目名がDATA、INDICATORおよびRETURNED_LENGTHの場合にのみ、それらの前にREFキーワードを指定します。REFキーワードを使用した場合は、GET文を使用する必要はありません。複合データ型およびDMLのRETURNING句には、SET DESCRIPTORのREF書式が必要です。「DML RETURNING句」を参照してください。

REFを使用すると、対応付けられたホスト変数自体がSETで使用されます。この場合、GETは必要ありません。値構文ではなく、REFセマンティクスを使用するときにのみ、RETURNED_LENGTHを設定できます。

SETまたはGET文の配列サイズは、FETCHで使用する配列サイズと同じにしてください。

NCHARホスト変数には、NATIONAL_CHARフィールドを2に設定します。

オブジェクト型の特性を設定するときは、USER_DEFINED_TYPE_NAMEおよびUSER_DEFINED_TYPE_NAME_LENGTHを設定する必要があります。

省略した場合は、USER_DEFINED_TYPE_SCHEMAおよびUSER_DEFINED_TYPE_SCHEMA_LENGTHはデフォルトで現行の接続に設定されます。

10.6.4.1

バルク表の例は、「バルク操作での表の使用方法」を参照してください。

 ...
 O1  BINDNO  PIC S9(9) COMP  VALUE 2.
 01  INDI    PIC S9(4) COMP  VALUE -1.
 01  DATA    PIC X(6)  COMP  VALUE "ignore".
 01  BATCH   PIC S9(9) COMP  VALUE 1.
 ...
     EXEC SQL FOR :batch ALLOCATE DESCRIPTOR :BINDDES END-EXEC.
     EXEC SQL SET DESCRIPTOR GLOBAL :BINDDES COUNT = 3 END-EXEC.
     EXEC SQL FOR :batch SET DESCRIPTOR :BINDDES
        VALUE :BINDNO INDICATOR = :INDI, DATA = :DATA END-EXEC.
...

10.6.5 PREPAREの使用

用途

この方法で使用するPREPARE文は、Oracle動的SQL方法で使用するPREPARE文と同じです。Oracle拡張機能によって、変数と同様にSQL文で引用符付き文字列を使用できます。

構文

     EXEC SQL PREPARE statement_id FROM :sql_statement END-EXEC.

変数

statement_id

この変数を宣言しないでください。これは、準備済のSQL文に対応付けられた宣言されていないSQL識別子です。

sql_statement

埋込みSQL文を格納する文字列(定数または変数)。

 ...
 01  STATEMENT    PIC X(255)
        VALUE "SELECT ENAME FROM emp WHERE deptno = :d".
 ...
     EXEC SQL PREPARE S1 FROM :STATEMENT END-EXEC.

10.6.6 DESCRIBE INPUT

用途

この文は、入力バインド変数に関する情報を戻します。

構文

     EXEC SQL DESCRIBE INPUT statement_id USING [SQL] DESCRIPTOR 
        [GLOBAL | LOCAL] {:desc_nam | string_literal}
     END-EXEC.

変数

statement_id

PREPAREおよびDESCRIBE OUTPUTで使用するものと同じです。これは宣言しないでください(これはSQL識別子です)。

GLOBAL | LOCAL

GLOBALは、すべてのプログラム・ファイルで記述子名が認識されることを示します。LOCALは、記述子名を割り当てたファイル内でのみ記述子名が認識されることを示します。LOCALがデフォルトです。

desc_nam

記述子名。

使用上の注意

このバージョンでは、COUNTおよびNAMEのみがバインド変数のために実装されています。

     EXEC SQL DESCRIBE INPUT S1 USING SQL DESCRIPTOR GLOBAL :BINDDES END-EXEC.
     EXEC SQL DESCRIBE INPUT S2 USING DESCRIPTOR 'input' END-EXEC.

10.6.7 DESCRIBE OUTPUT

用途

DESCRIBE INPUT文は、PREPARE文の列に関する情報を取得するために使用します。ANSI構文は以前の構文と違います。SQL記述子領域に格納される情報は、戻された値の個数、および関連する情報(型、長さ、名前など)です。

構文

     EXEC SQL DESCRIBE [OUTPUT] statement_id USING [SQL] DESCRIPTOR
        [GLOBAL | LOCAL] {:desc_nam | string_literal}
     END-EXEC.

変数

statement_id

statement_idはSQL識別子です。宣言しないでください。

GLOBAL | LOCAL

GLOBALは、すべてのプログラム・ファイルで記述子名が認識されることを示します。LOCALは、記述子名を割り当てたファイル内でのみ記述子名が認識されることを示します。LOCALがデフォルトです。

desc_nam

記述子名。ホスト変数の前に「:」を付けたもの、または引用符付き文字列。OUTPUTがデフォルト設定で、これは省略できます。

 ...
 01  DESNAME   PIC X(10) VALUE "SELDES".
 ...
     EXEC SQL DESCRIBE S1 USING SQL DESCRIPTOR 'SELDES' END-EXEC. 
* Or:
     EXEC SQL DESCRIBE OUTPUT S1 USING DESCRIPTOR :DESNAME END-EXEC.

10.6.8 EXECUTE

用途

EXECUTEは、準備済のSQL文の入力変数および出力変数を照合し、文を実行します。ANSIバージョンのEXECUTEは、以前のEXECUTEとは違い、DML RETURNINGをサポートするために1つの文に記述子を2つ使用できます。

構文

     EXEC SQL [FOR [:]array_size] EXECUTE statement_id 
        [USING [SQL] DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}] 
        [INTO [SQL] DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}]
     END-EXEC.

変数

array_size

文が処理する行数。

statement_id

PREPAREで使用するものと同じです。これは宣言しないでください(これはSQL識別子です)。リテラルを指定できます。

GLOBAL | LOCAL

GLOBALは、すべてのプログラム・ファイルで記述子名が認識されることを示します。LOCALは、記述子名を割り当てたファイル内でのみ記述子名が認識されることを示します。LOCALがデフォルトです。

desc_nam

記述子名。ホスト変数の前に「:」を付けたもの、または引用符付き文字列。

使用上の注意

INTO句は、INSERT、UPDATEおよびDELETEのRETURNING句を実装します(「行の挿入」とその後のページを参照してください)。

     EXEC SQL EXECUTE S1 USING SQL DESCRIPTOR GLOBAL :BINDDES END-EXEC.

     EXEC SQL EXECUTE S2 USING DESCRIPTOR :bv1 INTO DESCRIPTOR 'SELDES'
        END-EXEC.

関連項目

10.6.9 EXECUTE IMMEDIATEの使用

用途

EXECUTE IMMEDIATE文は、SQL文を含むリテラル文字列またはホスト変数文字列を実行します。この文のANSI SQL書式は、以前の動的SQLと同じです。

構文

     EXEC SQL EXECUTE IMMEDIATE [:]sql_statement END-EXEC.

変数

EXECUTE IMMEDIATE文で使用できる変数は1つです。

sql_statement

sql_statement変数は、文字列内のSQL文またはPL/SQLブロックです。ホスト変数にもリテラルにも使用できます。

     EXEC SQL EXECUTE IMMEDIATE :statement END-EXEC.

10.6.10 DYNAMIC DECLARE CURSORの使用

用途

DYNAMIC DECLARE CURSOR文は、問合せ文に対応付けられたカーソルを宣言します。これは、一般的なカーソル宣言部です。

構文

     EXEC SQL DECLARE cursor_name CURSOR FOR statement_id END-EXEC.

変数

cursor_name

カーソル変数(SQL識別子であり、ホスト変数ではありません)。

statement_id

未定義のSQL識別子(PREPARE文で使用するものと同じです)。

     EXEC SQL DECLARE C1 CURSOR FOR S1 END-EXEC. 

10.6.11 カーソルのOPEN

用途

OPEN文は、入力パラメータとカーソルとを対応付け、カーソルをオープンします。

構文

     EXEC SQL [FOR [:]array_size] OPEN dyn_cursor 
        [[USING [SQL] DESCRIPTOR [GLOBAL | LOCAL] desc_nam1]
        [INTO [SQL] DESCRIPTOR [GLOBAL | LOCAL] desc_nam2] ]
     END-EXEC.

変数

array_size

この変数は、記述子を割り当てた時に指定した数と等しいか、それよりも小さい数に制限されます。

GLOBAL | LOCAL

GLOBALは、すべてのプログラム・ファイルで記述子名が認識されることを示します。LOCALは、記述子名を割り当てたファイル内でのみ記述子名が認識されることを示します。LOCALがデフォルトです。

dyn_cursor

カーソル変数。

desc_nam1、desc_nam2

オプションの記述子名。

使用上の注意

カーソルに対応付けられた準備済の文にコロンまたは疑問符が含まれる場合は、USING句を指定する必要があります。指定しない場合は、ランタイム・エラーが発生します。INTO句はDML RETURNINGをサポートしています(「行の挿入」およびそれ以降のDELETEおよびUPDATEに関する項を参照してください)。

     EXEC SQL OPEN C1 USING SQL DESCRIPTOR :BINDDES END-EXEC.

     EXEC SQL FOR :LIMIT OPEN C2 USING DESCRIPTOR :B1, :B2 
       INTO SQL DESCRIPTOR :SELDES
     END-EXEC.

関連項目

10.6.12 FETCH

用途

FETCH文は、動的DECLARE文で宣言したカーソルの行をフェッチします。

構文

     EXEC SQL [FOR [:]array_size] FETCH cursor INTO [SQL] DESCRIPTOR 
       [GLOBAL | LOCAL] {:desc_nam | string_literal}
     END-EXEC.

変数

array_size

文が処理する行数。

cursor

事前に宣言された動的カーソル。

GLOBAL | LOCAL

GLOBALは、すべてのプログラム・ファイルで記述子名が認識されることを示します。LOCALは、記述子名を割り当てたファイル内でのみ記述子名が認識されることを示します。LOCALがデフォルトです。

desc_nam

記述子の名前。

使用上の注意

FOR句のarray_sizeオプションは、ALLOCATE DESCRIPTOR文で指定された数以下にする必要があります。

RETURNED_LENGTHは、固定長キャラクタ・タイプに対しては未定義になります。

     EXEC SQL FETCH FROM C1 INTO DESCRIPTOR 'SELDES' END-EXEC.

     EXEC SQL FOR :ARSZ FETCH C2 INTO DESCRIPTOR :DESC END-EXEC.

10.6.13 動的カーソルのCLOSE

用途

CLOSE文は動的カーソルをクローズします。構文は方法4の場合と同じです。

構文

     EXEC SQL CLOSE cursor END-EXEC.

変数

CLOSE文で使用できる変数は1つです。

cursor

カーソル変数は、前に宣言した動的カーソルを記述します。

     EXEC SQL CLOSE C1 END-EXEC.

10.6.14 Oracle動的方法4との違い

ANSI動的SQLインタフェースでは、Oracle動的方法4でサポートされる機能がすべてサポートされており、それ以外に次のサポートが追加されています。

  • ANSI動的SQLでは、すべてのデータ型(カーソル変数を含む)およびLOB型がサポートされます。

  • ANSIモードでは、内部のSQL記述領域が使用されますが、これは、Oracleの以前の動的方法4で入力および出力情報の格納に使用される外部SQLDAを拡張したものです。

  • ALLOCATE DESCRIPTOR、DEALLOCATE DESCRIPTOR、DESCRIBE、GET DESCRIPTORおよびSET DESCRIPTORという新しい埋込みSQL文が導入されています。

  • ANSI動的SQLでは、DESCRIBE文は標識変数の名前を戻しません。

  • ANSI動的SQLでは、戻される列名または式の最大サイズを指定できません。デフォルト・サイズは128に設定されます。

  • 記述子名は、引用符で囲んだ識別子、または先頭にコロンをつけたホスト変数のどちらかであることが必要です。

  • 出力時に、DESCRIBE文のSELECT LIST FOR句はオプション・キーワードOUTPUTに置き換えられます。INTO句はUSING DESCRIPTOR句に置き換えられます。この句には、オプション・キーワードSQLを含めることができます。

  • 入力時に、DESCRIBE文のオプションのBIND VARIABLES FOR句をキーワードINPUTに置き換えることができます。INTO句はUSING DESCRIPTOR句に置き換えられます。この句には、オプション・キーワードSQLを含めることができます。

  • EXECUTE、FETCHおよびOPEN文でUSING句のキーワードDESCRIPTORの前にオプション・キーワードSQLを指定できます。

10.6.15 制限事項

ANSI動的SQLには次の制限が適用されます。

  • 同じモジュール内で2つの動的方法は併用できません。

  • プリコンパイラ・オプションDYNAMICをANSIに設定する必要があります。DYNAMICをANSIに設定したときにのみ、プリコンパイラ・オプションTYPE_CODEをANSIに設定できます。

  • SET文は、項目名としてのホスト変数のみサポートします。

10.7 サンプル・プログラム: SAMPLE12.PCO

次のANSI SQL動的方法4プログラムSAMPLE12.PCOは、デモ・ディレクトリにあります。SAMPLE12は、ユーザーが入力するSQL文を要求することによってSQL*Plusを模造したプログラムです。プログラムの流れの詳細は、最初のコメントを参照してください。

      ******************************************************************
      * Sample Program 12: Dynamic SQL Method 4 using ANSI Dynamic SQL *
      *                                                                *
      * This program shows the basic steps required to use dynamic     *
      * SQL Method 4 with ANSI Dynamic SQL.  After logging on to       *
      * ORACLE, the program prompts the user for a SQL statement,      *
      * PREPAREs the statement, DECLAREs a cursor, checks for any      *
      * bind variables using DESCRIBE INPUT, OPENs the cursor, and     *
      * DESCRIBEs any select-list variables.  If the input SQL         *
      * statement is a query, the program FETCHes each row of data,    *
      * then CLOSEs the cursor.                                        *
      * use option dynamic=ansi when precompiling this sample.         *
      ******************************************************************

       IDENTIFICATION DIVISION.
       PROGRAM-ID.  ANSIDYNSQL4.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.

       01  USERNAME       PIC X(20).
       01  PASSWD         PIC X(20).
       01  BDSC           PIC X(6) VALUE "BNDDSC".
       01  SDSC           PIC X(6) VALUE "SELDSC".
       01  BNDCNT         PIC S9(9) COMP.
       01  SELCNT         PIC S9(9) COMP.
       01  BNDNAME        PIC X(80).
       01  BNDVAL         PIC X(80).
       01  SELNAME        PIC X(80) VARYING.
       01  SELDATA        PIC X(80).
       01  SELTYP         PIC S9(4) COMP.
       01  SELPREC        PIC S9(4) COMP.
       01  SELLEN         PIC S9(4) COMP.
       01  SELIND         PIC S9(4) COMP.
       01  DYN-STATEMENT  PIC X(80).
       01  BND-INDEX      PIC S9(9) COMP.
       01  SEL-INDEX      PIC S9(9) COMP.
       01  VARCHAR2-TYP   PIC S9(4) COMP VALUE 1.
       01  VAR-COUNT      PIC 9(2).
       01  ROW-COUNT      PIC 9(4).
       01  NO-MORE-DATA   PIC X(1) VALUE "N".
       01  TMPLEN         PIC S9(9) COMP.
       01  MAX-LENGTH     PIC S9(9) COMP VALUE 80.

           EXEC SQL INCLUDE SQLCA         END-EXEC.

       PROCEDURE DIVISION.
       START-MAIN.

           EXEC SQL WHENEVER SQLERROR GOTO SQL-ERROR END-EXEC.

           DISPLAY "USERNAME: " WITH NO ADVANCING.
           ACCEPT USERNAME.
           DISPLAY "PASSWORD: " WITH NO ADVANCING.
           ACCEPT PASSWD.
           EXEC SQL CONNECT :USERNAME IDENTIFIED BY :PASSWD END-EXEC.
           DISPLAY "CONNECTED TO ORACLE AS USER: ", USERNAME.

      *    ALLOCATE THE BIND AND SELECT DESCRIPTORS.

           EXEC SQL ALLOCATE DESCRIPTOR :BDSC WITH MAX 20 END-EXEC.
           EXEC SQL ALLOCATE DESCRIPTOR :SDSC WITH MAX 20 END-EXEC.

      *    GET A SQL STATEMENT FROM THE OPERATOR.

           DISPLAY "ENTER SQL STATEMENT WITHOUT TERMINATOR:".
           DISPLAY ">" WITH NO ADVANCING.
           ACCEPT DYN-STATEMENT.
           DISPLAY " ".

      *    PREPARE THE SQL STATEMENT AND DECLARE A CURSOR.

           EXEC SQL  PREPARE S1 FROM :DYN-STATEMENT  END-EXEC.
           EXEC SQL  DECLARE C1 CURSOR FOR S1        END-EXEC.

      *    DESCRIBE BIND VARIABLES.

           EXEC SQL DESCRIBE INPUT S1 USING DESCRIPTOR :BDSC END-EXEC.

           EXEC SQL GET DESCRIPTOR :BDSC :BNDCNT = COUNT END-EXEC.

           IF BNDCNT < 0
               DISPLAY "TOO MANY BIND VARIABLES."
               GO TO END-SQL
           ELSE
               DISPLAY "NUMBER OF BIND VARIABLES: " WITH NO ADVANCING
               MOVE BNDCNT TO VAR-COUNT
               DISPLAY VAR-COUNT
      *        EXEC SQL SET DESCRIPTOR :BDSC COUNT = :BNDCNT END-EXEC
           END-IF.

           IF BNDCNT = 0
               GO TO DESCRIBE-ITEMS.
           PERFORM SET-BND-DSC
                   VARYING BND-INDEX FROM 1 BY 1
                   UNTIL BND-INDEX > BNDCNT.

      *    OPEN THE CURSOR AND DESCRIBE THE SELECT-LIST ITEMS.

       DESCRIBE-ITEMS.
           EXEC SQL  OPEN C1 USING DESCRIPTOR :BDSC END-EXEC.

           EXEC SQL  DESCRIBE OUTPUT S1 USING DESCRIPTOR :SDSC  END-EXEC.

           EXEC SQL GET DESCRIPTOR :SDSC :SELCNT = COUNT END-EXEC.

           IF SELCNT < 0
               DISPLAY "TOO MANY SELECT-LIST ITEMS."
               GO TO END-SQL
           ELSE
               DISPLAY "NUMBER OF SELECT-LIST ITEMS: "
                   WITH NO ADVANCING
               MOVE SELCNT TO VAR-COUNT
               DISPLAY VAR-COUNT
               DISPLAY " "
      *        EXEC SQL SET DESCRIPTOR :SDSC COUNT = :SELCNT END-EXEC
           END-IF.

      *    SET THE INPUT DESCRIPTOR

           IF SELCNT > 0
               PERFORM SET-SEL-DSC
                   VARYING SEL-INDEX FROM 1 BY 1
                   UNTIL SEL-INDEX > SELCNT
               DISPLAY " ".

      *    FETCH EACH ROW AND PRINT EACH SELECT-LIST VALUE.

           IF SELCNT > 0
               PERFORM FETCH-ROWS UNTIL NO-MORE-DATA = "Y".

           DISPLAY " "
           DISPLAY "NUMBER OF ROWS PROCESSED: " WITH NO ADVANCING.
           MOVE SQLERRD(3) TO ROW-COUNT.
           DISPLAY ROW-COUNT.

      *    CLEAN UP AND TERMINATE.

           EXEC SQL CLOSE C1 END-EXEC.
           EXEC SQL DEALLOCATE DESCRIPTOR :BDSC END-EXEC.
           EXEC SQL DEALLOCATE DESCRIPTOR :SDSC END-EXEC.
           EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
           DISPLAY " ".
           DISPLAY "HAVE A GOOD DAY!".
           DISPLAY " ".
           STOP RUN.

      *    DISPLAY ORACLE ERROR MESSAGE AND CODE.

       SQL-ERROR.
           DISPLAY " ".
           DISPLAY SQLERRMC.
       END-SQL.
           EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
           EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
           STOP RUN.

      *    PERFORMED SUBROUTINES BEGIN HERE:

      *    SET A BIND-LIST ELEMENT'S ATTRIBUTE
      *    LET THE USER FILL IN THE BIND VARIABLES AND
      *    REPLACE THE 0S DESCRIBED INTO THE DATATYPE FIELDS OF THE
      *    BIND DESCRIPTOR WITH 1S TO AVOID AN "INVALID DATATYPE"
      *    ORACLE ERROR
       SET-BND-DSC.
               EXEC SQL GET DESCRIPTOR :BDSC VALUE
                      :BND-INDEX :BNDNAME = NAME END-EXEC.
               DISPLAY "ENTER VALUE FOR ", BNDNAME.
               ACCEPT BNDVAL.
               EXEC SQL SET DESCRIPTOR :BDSC VALUE :BND-INDEX
                 TYPE = :VARCHAR2-TYP, LENGTH = :MAX-LENGTH, 
                 DATA = :BNDVAL END-EXEC.

      * SET A SELECT-LIST ELEMENT'S ATTRIBUTES
       SET-SEL-DSC.
           MOVE SPACES TO SELNAME-ARR.
           EXEC SQL GET DESCRIPTOR :SDSC VALUE :SEL-INDEX
                 :SELNAME = NAME, :SELTYP = TYPE,
                 :SELPREC = PRECISION, :SELLEN = LENGTH END-EXEC.

      *    IF DATATYPE IS DATE, LENGTHEN TO 9 CHARACTERS.
           IF SELTYP = 12
               MOVE 9 TO SELLEN.

      *    IF DATATYPE IS NUMBER, SET LENGTH TO PRECISION.
           MOVE 0 TO TMPLEN. 
           IF SELTYP = 2 AND SELPREC = 0
               MOVE 40 TO TMPLEN.
           IF SELTYP = 2 AND SELPREC > 0
               ADD 2 TO SELPREC
               MOVE SELPREC TO TMPLEN.

           IF SELTYP = 2
               IF TMPLEN > MAX-LENGTH
                   DISPLAY "COLUMN VALUE TOO LARGE FOR DATA BUFFER."
                   GO TO END-SQL
               ELSE
                   MOVE TMPLEN TO SELLEN.


      * COERCE DATATYPES TO VARCHAR2.
           MOVE 1 TO SELTYP.

      *    DISPLAY COLUMN HEADING.
           DISPLAY "  ", SELNAME-ARR(1:SELLEN) WITH NO ADVANCING.

           EXEC SQL SET DESCRIPTOR :SDSC VALUE :SEL-INDEX
              TYPE = :SELTYP, LENGTH = :SELLEN END-EXEC.

      * FETCH A ROW AND PRINT THE SELECT-LIST VALUE.

       FETCH-ROWS.
           EXEC SQL  FETCH C1 INTO DESCRIPTOR :SDSC END-EXEC.
           IF SQLCODE NOT = 0
               MOVE "Y" TO NO-MORE-DATA.
           IF SQLCODE = 0
               PERFORM PRINT-COLUMN-VALUES
                   VARYING SEL-INDEX FROM 1 BY 1
                   UNTIL SEL-INDEX > SELCNT
               DISPLAY " ".

      * PRINT A SELECT-LIST VALUE.

       PRINT-COLUMN-VALUES.
           MOVE SPACES TO SELDATA.
      *    returned length is not set for blank padded types
           IF SELTYP EQUALS 1
              EXEC SQL GET DESCRIPTOR :SDSC VALUE :SEL-INDEX
                :SELDATA = DATA, :SELIND = INDICATOR, 
                :SELLEN = LENGTH END-EXEC
           ELSE    
              EXEC SQL GET DESCRIPTOR :SDSC VALUE :SEL-INDEX
                 :SELDATA = DATA, :SELIND = INDICATOR, 
                 :SELLEN = RETURNED_LENGTH END-EXEC.
           IF (SELIND = -1)
              move "  NULL" to SELDATA.

           DISPLAY SELDATA(1:SELLEN), "  " 
                 WITH NO ADVANCING.