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_CODE
をANSI
に設定するには、DYNAMIC
もANSI
に設定する必要があります。
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.
hv1
、hv2
および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) COMP
かPIC 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
には、Tom
、Dick
および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はインラインでは使用できません。
表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以外には設定できません。
表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.2 DEALLOCATE DESCRIPTOR
用途
メモリーを解放するには、割当て解除文を使用します。この文は、事前に割り当てたSQL記述子領域を解除します。
構文
EXEC SQL DEALLOCATE DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} END-EXEC.
変数
例
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 記述子項目名の定義
記述子項目名 | 意味 |
---|---|
|
ANSI型コードは表10-1を参照してください。Oracle型コードは表11-2を参照してください。ANSIデータ型が表になく、TYPE_CODE = ANSIである場合は、Oracleコードの負の値を使用してください。 |
|
列内のデータの長さ。NCHARは文字単位、それ以外はバイト単位です。DESCRIBE OUTPUTによって設定されます。 |
|
バイト単位でのデータの長さ。 |
|
FETCH後の実際のデータ長。固定長キャラクタ・タイプについては未定義になります。 |
|
戻されたデータのバイト単位での長さ。 |
|
桁数。 |
|
真数値型での小数点の右側の桁数。 |
|
1のときは、列にNULL値を使用できます。0のときは、列にNULL値は使用できません。 |
|
対応付けられたインジケータ値。 |
|
データの値。 |
|
列の名前。 |
|
列の文字セット。 |
次の表に、記述子項目名のOracle拡張機能を示します。
表10-5 記述子項目名の定義のOracle拡張機能
記述子項目名 | 意味 |
---|---|
|
2はNCHARまたはNVARCHAR2を示します。1の場合は文字です。0の場合は文字以外の値です。 |
|
内部でのバイト単位の長さ。 |
使用上のノート
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.
変数
例
... 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.
変数
例
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.
変数
例
... 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.
変数
使用上のノート
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つです。
例
EXEC SQL EXECUTE IMMEDIATE :statement 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.
変数
使用上のノート
カーソルに対応付けられた準備済の文にコロンまたは疑問符が含まれる場合は、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.
変数
使用上のノート
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.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.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.