動的SQL文で記述子を使用する前に、記述子領域を割り当てます。
ALLOCATE DESCRIPTOR文の構文は次のとおりです。
EXEC SQL ALLOCATE DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} [WITH MAX {:occurrences | numeric_literal}];
グローバル記述子は、プログラム内の任意のモジュールで使用できます。ローカル記述子は、その記述子を割り当てたファイル内でのみアクセス可能です。デフォルトはローカルです。
記述子名のdesc_nam
には、引用符で囲んだリテラルまたはホスト変数に格納した文字値を代入できます。
occurrences
は、記述子が保持できるバインド変数または列数の最大値です。数値リテラルを指定する必要があります。デフォルトは100です。
記述子が必要なくなった場合は、割当てを解除してメモリーを節約します。それ以外の場合には、アクティブなデータベース接続がなくなった時点で自動的に割当てが解除されます。
割当て解除文は次のとおりです。
EXEC SQL DEALLOCATE DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal};
準備済のSQL文に関する情報を取得するには、DESCRIBE文を使用します。DESCRIBE INPUTでは、準備済の動的文のバインド変数が記述されます。DESCRIBE OUTPUT (デフォルト)では、出力列の番号、型および長さが記述されます。単純化した構文は次のとおりです。
EXEC SQL DESCRIBE [INPUT | OUTPUT] sql_statement USING [SQL] DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal};
SQL文に入力値および出力値がある場合は、入力値および出力値に1つずつ記述子を割り当てる必要があります。入力値がない次の例のような場合があります。
SELECT ename, empno FROM emp ;
この場合、入力記述子は必要ありません。
SELECT文のINSERTS、UPDATES、DELETESおよびWHERE句の入力値を指定するには、SET DESCRIPTOR文を使用します。入力記述子内にDESCRIBEしていないときに入力バインド変数の数(COUNT
に格納されています)を設定するには、SET DESCRIPTOR文を使用します。
EXEC SQL SET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} COUNT = {:kount | numeric_literal};
kount
には、ホスト変数または数値リテラル(5など)を指定できます。SET DESCRIPTOR文を使用して、各ホスト変数に少なくともデータ・ソースを指定してください。
EXEC SQL SET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} VALUE item_number DATA = :hv3;
また、次のように入力ホスト変数の型および長さを設定することもできます。
注意:
TYPE_CODE=ORACLEのとき、SET文を使用して明示的に、またはDESCRIBE OUTPUTによって暗黙的にTYPEおよびLENGTHを指定していない場合、プリコンパイラではホスト変数から導出された値が使用されます。TYPE_CODE=ANSIのときは、表14-1の値を使用してTYPEを設定する必要があります。また、ANSIデフォルト長はホスト変数に一致しないことがあるため、LENGTHも設定する必要があります。
EXEC SQL SET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} VALUE item_number TYPE = :hv1, LENGTH = :hv2, DATA = :hv3;
hv1
、hv2
およびhv3
などの識別子は、ホスト変数から値を供給する必要があることをユーザーが忘れないようにするために使用します。item_numberは、入力変数のSQL文内での位置を表します。
TYPE_CODEをANSIに設定した場合は、次の表の型コードからTYPEを選択します。
表14-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型コードは表15-2を参照してください
DATAは、入力されるホスト変数の値です。
インジケータ、精度、位取りなど、その他の入力値を設定することもできます。
関連項目:
可能な記述子項目名の詳細は、SET DESCRIPTORを参照してください。
SET DESCRIPTOR文の数値は、int
またはshort int
で宣言する必要があります。ただし、インジケータおよび戻された長さの値はshort int
として宣言する必要があります。
たとえば、次の例でempno
を取得する場合、empno
は動的SQL文の2番目の出力ホスト変数であるため、値をVALUE = 2に設定します。ホスト変数empno_typ
は、3(Oracleタイプの整数値)に設定します。ホスト整数の長さを表すempno_len
は、4に設定します。この値はホスト変数のサイズです。DATAはホスト変数empno_data
と等しくなります。この変数は値をデータベース表から受け取ります。コード例は、次のようになります。
... char *dyn_statement = "SELECT ename, empno FROM emp WHERE deptno = :deptno_number" ; int empno_data ; int empno_typ = 3 ; int empno_len = 4 ; ... EXEC SQL SET DESCRIPTOR 'out' VALUE 2 TYPE = :empno_typ, LENGTH = :empno_len, DATA = :empno_data ;
入力値を設定後に、入力記述子を使用して文を実行またはオープンします。文中に出力値がある場合、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 ;
desc_nam
およびitem_number
には、リテラルまたはホスト変数を指定できます。記述子名には、リテラル(outなど)を指定できます。項目番号には、数値リテラル(2など)を指定できます。
hv1、hv2およびhv3
は、それぞれホスト変数です。ここにはホスト変数を指定する必要があり、リテラルは指定できません。例では、戻されるデータを3つのみ示しています。
数値すべてにlong、intまたはshortのいずれかを指定します。ただし、インジケータまたは戻された長さの値はshort
にする必要があります。
関連項目:
戻されたデータから取得できるすべての項目の一覧については、表14-4を参照してください。
次の例は、ANSI動的SQLの使用方法を示しています。ここでは入力記述子('in')および出力記述子('out')を割り当ててSELECT文を実行します。入力値はSET DESCRIPTOR文を使用して設定します。カーソルはオープンおよびフェッチされ、結果の出力値はGET DESCRIPTOR文を使用して取得されます。
... char* dyn_statement = "SELECT ename, empno FROM emp WHERE deptno = :deptno_data" ; int deptno_type = 3, deptno_len = 2, deptno_data = 10 ; int ename_type = 97, ename_len = 30 ; char ename_data[31] ; int empno_type = 3, empno_len = 4 ; int empno_data ; long SQLCODE = 0 ; ... main () { /* Place preliminary code, including connection, here. */ ... EXEC SQL ALLOCATE DESCRIPTOR 'in' ; EXEC SQL ALLOCATE DESCRIPTOR 'out' ; EXEC SQL PREPARE s FROM :dyn_statement ; EXEC SQL DESCRIBE INPUT s USING DESCRIPTOR 'in' ; EXEC SQL SET DESCRIPTOR 'in' VALUE 1 TYPE = :deptno_type, LENGTH = :deptno_len, DATA = :deptno_data ; EXEC SQL DECLARE c CURSOR FOR s ; EXEC SQL OPEN c USING DESCRIPTOR 'in' ; EXEC SQL DESCRIBE OUTPUT s USING DESCRIPTOR 'out' ; EXEC SQL SET DESCRIPTOR 'out' VALUE 1 TYPE = :ename_type, LENGTH = :ename_len, DATA = :ename_data ; EXEC SQL SET DESCRIPTOR 'out' VALUE 2 TYPE = :empno_type, LENGTH = :empno_len, DATA = :empno_data ; EXEC SQL WHENEVER NOT FOUND DO BREAK ; while (SQLCODE == 0) { EXEC SQL FETCH c INTO DESCRIPTOR 'out' ; EXEC SQL GET DESCRIPTOR 'out' VALUE 1 :ename_data = DATA ; EXEC SQL GET DESCRIPTOR 'out' VALUE 2 :empno_data = DATA ; printf("\nEname = %s Empno = %s", ename_data, empno_data) ; } EXEC SQL CLOSE c ; EXEC SQL DEALLOCATE DESCRIPTOR 'in' ; EXEC SQL DEALLOCATE DESCRIPTOR 'out' ; ... }
ANSI動的SQLとともにスクロール可能カーソルを使用することもできます。ANSI動的SQLをスクロール可能カーソルとともに使用するには、カーソルをSCROLLモードでDECLAREします。FETCH文に様々なフェッチ方向を使用して、結果セットにアクセスします。