SQL文の条件だけを動的に変更してデータ操作を行う場合は、動的パラメタ指定を指定します。入力する値をホスト変数に格納します。ホスト変数の値を設定するためには、動的パラメタ指定の情報をそのホスト変数の属性と一致させることが必要です。そこで、データベースからSQL記述子域に動的パラメタ指定の情報を取り込んで、属性を変更し、値を設定します。SQL記述子域の位置づけを以下に示します。

SQL記述子域は、識別子COUNTと0以上の項目記述子域(SQL記述子域の各要素)で構成されています。COUNTは、SQL記述子域の動的パラメタ指定の数を示し、そのデータ型は2進の精度を持つ真数です。以下の図では、SQL記述子域の動的パラメタ指定の数をnで表しています。

SQL記述子域の詳細については、“4.2.2 SQL文の準備とSQL記述子域の操作”を参照してください。
動的パラメタ指定値の設定手順
USING記述子を使用して、動的パラメタ指定の値を設定する方法の順序を以下に示します。
図4.4 被準備文の動的パラメタ指定値の設定手順

“図4.4 被準備文の動的パラメタ指定値の設定手順”で示したように、データベースからSQL記述子域に動的パラメタ指定の情報を取り込んだり、SQL記述子域に取り込まれた動的パラメタ指定の情報を取得するには、それぞれSQL文を使用します。SQL記述子域を操作するSQL文とその機能について以下で説明します。
DESCRIBE文では、PREPARE文で準備された被準備文の動的パラメタ指定の情報をSQL記述子域に取り込みます。このSQL文を“入力DESCRIBE文”といいます。DESCRIBE文で指定した記述子名が動的OPEN文に指定されている場合、カーソルは閉じられた状態であることが必要です。
SQL文識別子STM1に対応する被準備文の動的パラメタ指定の情報を、SQL記述子域に取り込む入力DESCRIBE文の例を以下に示します。
DESCRIBE INPUT STM1 USING SQL DESCRIPTOR 'DESC1' (1) (2)
(1) SQL文識別子
(2) 記述子名
SQL文識別子STM1に対する被準備文が以下の場合、SQL記述子域DESC1の内容は次のようになります。
INSERT INTO 在庫管理.在庫表(製品番号, 製品名, 在庫数量) VALUES(?, ?, ?)
                                                             (1)(1) 動的パラメタ指定
COUNT : 3
動的パラメタ指定の個数3が設定されます。
項目記述子域
製品番号、製品名、在庫数量の属性がそれぞれ設定されます。
製品番号: SMALLINT(NOT NULL制約あり)
製品名 : NATIONAL CHARACTER (10) (NOT NULL制約あり)
在庫数量: INTEGER(NOT NULL制約なし)
識別子  | 製品番号  | 製品名  | 在庫数量  | 
|---|---|---|---|
TYPE  | 5  | 1  | 4  | 
LENGTH  | 2  | 10  | 4  | 
OCTET_LENGTH  | 2  | 20  | 4  | 
PRECISION  | 15  | 0  | 31  | 
SCALE  | 0  | 0  | 0  | 
NULLABLE  | 0  | 0  | 1  | 
INDICATOR  | 値は設定されない  | 値は設定されない  | 値は設定されない  | 
DATA  | 値は設定されない  | 値は設定されない  | 値は設定されない  | 
NAME  | 製品番号 (注)  | 製品名 (注)  | 在庫数量 (注)  | 
CHARACTER_SET_NAME  | 38バイトの空白  | NCHAR (注)  | 38バイトの空白  | 
DATETIME_INTERVAL_CODE  | 0  | 0  | 0  | 
DATETIME_INTERVAL_PRECISION  | 0  | 0  | 0  | 
注) 38バイトに満たない場合は、残りの部分に空白が設定されます。
DESCRIPTOR取得文では、SQL記述子域に設定されている情報をホスト変数に取り出します。ホスト変数のデータ型は、取得識別子に対応するデータ型と一致していることが必要です。
動的パラメタ指定の個数を、ホスト変数varcountに取得する例を以下に示します。
GET DESCRIPTOR 'DESC1' :varcount = COUNT (1) (2) (3)
(1) 記述子名
(2) 単純相手指定
(3) 取得識別子
SQL記述子域に設定されている動的パラメタ指定の内容を、それぞれホスト変数vartype、varleng、varoctetに取得する例を以下に示します。また、取得する項目記述子域の要素番号はvarwcountに設定されている値とします。
GET DESCRIPTOR 'DESC1' VALUE :varwcount :vartype = TYPE, (1) (2) (3) (4) :varleng = LENGTH, :varoctet = OCTET_LENGTH (3) (4) (3) (4)
(1) 記述子名
(2) SQLVAR取得番号
(3) 単純相手指定
(4) 取得識別子
DESCRIPTOR設定文では、動的パラメタ指定のデータ型と値をSQL記述子域に設定します。定数またはホスト変数で指定します。ホスト変数のデータ型は、それぞれ設定識別子のデータ型と一致していることが必要です。また、DESCRIPTOR設定文で指定した記述子名が動的OPEN文に指定されている場合、カーソルは閉じられた状態であることが必要です。
SQL記述子域の動的パラメタ指定のデータ型を変更し、値を設定する例を以下に示します。ここでは、設定を行う値が格納されているホスト変数vardataのデータ型が、CHARACTER(11)と宣言されているとします。したがって、動的パラメタ指定のデータ型をCHARACTER(10)に変更します。設定を行う項目記述子域の要素番号はvarwcountに設定されている値とします。
SET DESCRIPTOR 'DESC1' VALUE :varwcount TYPE = 1, (1) (2) (3) (4) LENGTH = 10, OCTET_LENGTH = 10, DATA = :vardata (3) (4) (3) (4) (3) (4)
(1) 記述子名
(2) SQLVAR設定番号
(3) 設定識別子
(4) 単純値指定
なお、ここでは、動的パラメタ指定の情報を持つSQL記述子域を操作するSQL文のみを説明しています。これ以外のSQL文については、“4.2.2 SQL文の準備とSQL記述子域の操作”を参照してください。
データの取り出しを連続的に行う場合には、動的SELECT文を準備して実行します。
SQL記述子域を使用して、動的パラメタ指定のある動的SELECT文を実行するアプリケーションの例を以下に示します。
端末から入力した動的SELECT文の例です。端末から入力した動的パラメタ指定の値を探索条件としてデータを検索し、その値を表示します。
#include <stdio.h>
#include <string.h>
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL INCLUDE varfile.h;                                                      …(1)
EXEC SQL END DECLARE SECTION;
void main()
 {
    memset(SQLSTATE, 0x00, 6);                                                   …(2)
    memset(SQLMSG, 0x00, 256);                                                   …(2)
    memset(&str, 0x00, sizeof(str));                                             …(2)
    memset(varname, 0x00, 39);                                                   …(2)
    memset(varchar, 0x00, 39);                                                   …(2)
    memset(&icdata, 0x00, sizeof(icdata));                                       …(2)
    memset(&incdata, 0x00, sizeof(incdata));                                     …(2)
    memset(&iddata, 0x00, sizeof(iddata));                                       …(2)
    memset(ocdata, 0x00, 15);                                                    …(2)
    memset(oncdata, 0x00, sizeof(oncdata));                                      …(2)
    memset(&oddata, 0x00, sizeof(oddata));                                       …(2)
    EXEC SQL CONNECT TO DEFAULT;                                                 …(3)
    EXEC SQL WHENEVER SQLERROR GOTO :ERR;                                        …(4)
    printf( "実行する動的SELECT文を指定してください \n" );
    gets( str.sqlvar );                                                          …(5)
    str.sqllen = strlen( str.sqlvar );
    EXEC SQL DECLARE CUR1 CURSOR FOR STMID;                                      …(6)
    EXEC SQL PREPARE STMID FROM :str;                                            …(7)
    EXEC SQL ALLOCATE DESCRIPTOR 'INDESC' WITH MAX 100;                          …(8)
    EXEC SQL ALLOCATE DESCRIPTOR 'OUTDESC' WITH MAX 100;                         …(9)
    EXEC SQL DESCRIBE INPUT STMID USING SQL DESCRIPTOR 'INDESC';                 …(10)
    EXEC SQL DESCRIBE OUTPUT STMID USING SQL DESCRIPTOR 'OUTDESC';               …(11)
    /********************/
    /* 動的パラメタ指定 */
    /********************/
    EXEC SQL GET DESCRIPTOR 'INDESC' :varicount = COUNT;                         …(12)
    for( i = 1; i <= varicount; i++ ) {
        EXEC SQL GET DESCRIPTOR 'INDESC' VALUE :i                                …(13)
                                         :vartype = TYPE,                        …(13)
                                         :varleng = LENGTH,                      …(13)
                                         :varolen = OCTET_LENGTH,                …(13)
                                         :varprec = PRECISION,                   …(13)
                                         :varscal = SCALE,                       …(13)
                                         :varname = NAME,                        …(13)
                                         :varchar = CHARACTER_SET_NAME,          …(13)
                                         :vardcod = DATETIME_INTERVAL_CODE,      …(13)
                                         :vardpre = DATETIME_INTERVAL_PRECISION; …(13)
        /* CHAR型かNCHAR型 */                                                    …(14)
        if( vartype == 1 || vartype == 12 ) {                                    …(14)
            /* 文字列型 */                                                       …(14)
            if( strncmp( varchar, "BASIC", 5 ) == 0 ) {                          …(14)
                printf( "%sの値を指定してください \n", varname );                …(14)
                scanf( "%s", icdata.sqlvar );                                    …(14)
                icdata.sqllen = strlen( icdata.sqlvar );                         …(14)
                EXEC SQL SET DESCRIPTOR 'INDESC' VALUE :i                        …(14)
                                                 TYPE = 1,                       …(14)
                                                 LENGTH = 14,                    …(14)
                                                 OCTET_LENGTH = 14,              …(14)
                                                 CHARACTER_SET_NAME = 'BASIC',   …(14)
                                                 DATA = :icdata;                 …(14)
            }                                                                    …(14)
            /* 各国語文字列型 */                                                 …(14)
            else {                                                               …(14)
                printf( "%sの値を指定してください \n", varname );                …(14)
                scanf( "%s", incdata.sqlvar );                                   …(14)
                incdata.sqllen = strlen( incdata.sqlvar );                       …(14)
                EXEC SQL SET DESCRIPTOR 'INDESC' VALUE :i                        …(14)
                                                 TYPE = 1,                       …(14)
                                                 LENGTH = 10,                    …(14)
                                                 OCTET_LENGTH = 20,              …(14)
                                                 CHARACTER_SET_NAME = 'NCHAR',   …(14)
                                                 DATA = :incdata;                …(14)
            }                                                                    …(14)
        }                                                                        …(14)
        /* INTEGER型かSMALLINT型 */                                              …(14)
        else if( vartype == 4 || vartype == 5 ) {                                …(14)
            printf( "%sの値を指定してください \n", varname );                    …(14)
            scanf( "%ld", &iidata );                                             …(14)
            EXEC SQL SET DESCRIPTOR 'INDESC' VALUE :i                            …(14)
                                             TYPE = 4,                           …(14)
                                             PRECISION = 31,                     …(14)
                                             SCALE = 0,                          …(14)
                                             INDICATOR = 0,                      …(14)
                                             DATA = :iidata;                     …(14)
        }                                                                        …(14)
        /* NUMERIC型かDECIMAL型かREAL型かDOUBLE PRECISION型 */                   …(14)
        else if( vartype == 2 || vartype == 3 ||                                 …(14)
                 vartype == 7 || vartype == 8 ) {                                …(14)
            printf( "%sの値を指定してください \n", varname );                    …(14)
            scanf( "%lf", &ifdata );                                             …(14)
            EXEC SQL SET DESCRIPTOR 'INDESC' VALUE :i                            …(14)
                                             TYPE = 8,                           …(14)
                                             PRECISION = 52,                     …(14)
                                             SCALE = 0,                          …(14)
                                             DATA = :ifdata;                     …(14)
        }                                                                        …(14)
        /* 日時型かINTERVAL型 */                                                 …(14)
        else if( vartype == 9 || vartype == 10 ) {                               …(14)
            printf( "%sの値を指定してください \n", varname );                    …(14)
            scanf( "%s", iddata.sqlvar );                                        …(14)
            iddata.sqllen = strlen( iddata.sqlvar );                             …(14)
            EXEC SQL SET DESCRIPTOR 'INDESC' VALUE :i                            …(14)
                                             TYPE = 12,                          …(14)
                                             LENGTH = 19,                        …(14)
                                             OCTET_LENGTH = 19,                  …(14)
                                             CHARACTER_SET_NAME = 'BASIC',       …(14)
                                             DATA = :iddata;                     …(14)
        }                                                                        …(14)
    }
    /**************/
    /* 選択リスト */
    /**************/
    EXEC SQL GET DESCRIPTOR 'OUTDESC' :varocount = COUNT;                        …(15)
    for( i = 1; i <= varocount; i++ ) {
        EXEC SQL GET DESCRIPTOR 'OUTDESC' VALUE :i
                                         :vartype = TYPE,                        …(16)
                                         :varleng = LENGTH,                      …(16)
                                         :varolen = OCTET_LENGTH,                …(16)
                                         :varprec = PRECISION,                   …(16)
                                         :varscal = SCALE,                       …(16)
                                         :varchar = CHARACTER_SET_NAME,          …(16)
                                         :vardcod = DATETIME_INTERVAL_CODE,      …(16)
                                         :vardpre = DATETIME_INTERVAL_PRECISION; …(16)
        /* CHAR型かNCHAR型 */                                                    …(17)
        if( vartype == 1 || vartype == 12 ) {                                    …(17)
            /* 文字列型 */                                                       …(17)
            if( strncmp( varchar, "BASIC", 5 ) == 0 ) {                          …(17)
                EXEC SQL SET DESCRIPTOR 'OUTDESC' VALUE :i                       …(17)
                                                  TYPE = 1,                      …(17)
                                                  LENGTH = 14,                   …(17)
                                                  OCTET_LENGTH = 14,             …(17)
                                                  CHARACTER_SET_NAME = 'BASIC';  …(17)
            }                                                                    …(17)
            /* 各国語文字列型 */                                                 …(17)
            else {                                                               …(17)
                EXEC SQL SET DESCRIPTOR 'OUTDESC' VALUE :i                       …(17)
                                                  TYPE = 1,                      …(17)
                                                  LENGTH = 10,                   …(17)
                                                  OCTET_LENGTH = 20,             …(17)
                                                  CHARACTER_SET_NAME = 'NCHAR';  …(17)
            }                                                                    …(17)
        }                                                                        …(17)
        /* INTEGER型かSMALLINT型 */                                              …(17)
        else if( vartype == 4 || vartype == 5 ) {                                …(17)
            EXEC SQL SET DESCRIPTOR 'OUTDESC' VALUE :i                           …(17)
                                              TYPE = 4,                          …(17)
                                              PRECISION = 31,                    …(17)
                                              SCALE = 0;                         …(17)
        }                                                                        …(17)
        /* NUMERIC型かDECIMAL型かREAL型かDOUBLE PRECISION型 */                   …(17)
        else if( vartype == 2 || vartype == 3 ||                                 …(17)
                 vartype == 7 || vartype == 8 ) {                                …(17)
            EXEC SQL SET DESCRIPTOR 'OUTDESC' VALUE :i                           …(17)
                                              TYPE = 8,                          …(17)
                                              PRECISION = 52,                    …(17)
                                              SCALE = 0;                         …(17)
        }                                                                        …(17)
        /* 日時型かINTERVAL型 */                                                 …(17)
        else if( vartype == 9 || vartype == 10 ) {                               …(17)
            EXEC SQL SET DESCRIPTOR 'OUTDESC' VALUE :i                           …(17)
                                              TYPE = 12,                         …(17)
                                              LENGTH = 19,                       …(17)
                                              OCTET_LENGTH = 19,                 …(17)
                                              CHARACTER_SET_NAME = 'BASIC';      …(17)
        }                                                                        …(17)
    }
    EXEC SQL OPEN CUR1 USING SQL DESCRIPTOR 'INDESC';                            …(18)
    EXEC SQL WHENEVER NOT FOUND GOTO :NOTFND;                                    …(19)
    for(;;) {
        EXEC SQL FETCH CUR1 INTO SQL DESCRIPTOR 'OUTDESC';                       …(20)
        /************/
        /* 実行結果 */
        /************/
        for( i = 1; i <= varocount; i++ ) {
            EXEC SQL GET DESCRIPTOR 'OUTDESC' VALUE :i                           …(21)
                                              :vartype = TYPE,                   …(21)
                                              :varchar = CHARACTER_SET_NAME;     …(21)
            /* CHAR型かNCHAR型 */                                                …(21)
            if( vartype == 1 ) {                                                 …(21)
                /* 文字列型 */                                                   …(21)
                if( strncmp( varchar, "BASIC", 5 ) == 0 ) {                      …(21)
                    EXEC SQL GET DESCRIPTOR 'OUTDESC' VALUE :i                   …(21)
                                                      :varname = NAME,           …(21)
                                                      :ocdata = DATA;            …(21)
                    printf( "%s -> %s   ", varname, ocdata );                    …(21)
                }                                                                …(21)
                /* 各国語文字列型 */                                             …(21)
                else {                                                           …(21)
                    EXEC SQL GET DESCRIPTOR 'OUTDESC' VALUE :i                   …(21)
                                                     :varname = NAME,            …(21)
                                                     :oncdata = DATA;            …(21)
                    printf( "%s -> %s   ", varname, oncdata );                   …(21)
                }                                                                …(21)
            }                                                                    …(21)
            /* 真数型 */                                                         …(21)
            else if( vartype == 4 ) {                                            …(21)
                EXEC SQL GET DESCRIPTOR 'OUTDESC' VALUE :i                       …(21)
                                                  :varname = NAME,               …(21)
                                                  :oidata = DATA;                …(21)
                printf( "%s -> %d   ", varname, oidata );                        …(21)
            }                                                                    …(21)
            /* 概数型 */                                                         …(21)
            else if( vartype == 8 ) {                                            …(21)
                EXEC SQL GET DESCRIPTOR 'OUTDESC' VALUE :i                       …(21)
                                                  :varname = NAME,               …(21)
                                                  :ofdata = DATA;                …(21)
                printf( "%s -> %lf   ", varname, ofdata );                       …(21)
            }                                                                    …(21)
            /* 日時型かINTERVAL型 */                                             …(21)
            else if( vartype == 12 ) {                                           …(21)
                EXEC SQL GET DESCRIPTOR 'OUTDESC' VALUE :i                       …(21)
                                                  :varname = NAME,               …(21)
                                                  :oddata = DATA;                …(21)
                oddata.sqlvar[oddata.sqllen] = \0;                               …(21)
                printf( "%s -> %s   \n", varname, oddata.sqlvar );               …(21)
            }                                                                    …(21)
        }
        printf( "\n" );
    }
NOTFND:
    EXEC SQL CLOSE CUR1;                                                         …(22)
    EXEC SQL DEALLOCATE DESCRIPTOR 'INDESC';                                     …(23)
    EXEC SQL DEALLOCATE DESCRIPTOR 'OUTDESC';                                    …(24)
    EXEC SQL DEALLOCATE PREPARE STMID;                                           …(25)
    EXEC SQL COMMIT WORK;                                                        …(26)
    EXEC SQL DISCONNECT DEFAULT;                                                 …(27)
    return;
ERR:
    EXEC SQL WHENEVER SQLERROR CONTINUE;
    printf( "SQLERROR SQLSTATE = %s SQLMSG = %s\n", SQLSTATE, SQLMSG );
    EXEC SQL ROLLBACK WORK;
    EXEC SQL DISCONNECT DEFAULT;
    return;
 }(1) インクルードファイルvarfile.hのホスト変数を展開します。SQL文変数はSQL文を格納する領域です。可変長文字列は、コンパイル時に以下の構造体に展開されます。
struct {
    short  sqllen;           /* 長さ領域の変数   */
    char   sqlvar[100];      /* 文字列領域の変数 */
}str;(2) ホスト変数を初期化します。
(3) コネクションを接続します。
(4) SQL文の実行でデータなし以外のエラーが生じた場合にERRへ進み、エラー情報を出力してプログラムは終了します。
(5) 端末から入力された動的SELECT文を読み込み、strに格納します。
(6) カーソルCUR1を宣言します。カーソル指定としてSQL文識別子STMIDを指定します。
(7) strのSQL文を実行できるようにするための準備処理を行います。
(8) 動的パラメタ指定のためのSQL記述子域INDESCを割り当てます。
(9) 相手指定のためのSQL記述子域OUTDESCを割り当てます。
(10) 入力した動的SELECT文の動的パラメタ指定の情報をSQL記述子域INDESCに取り込みます。
(11) 入力した動的SELECT文の選択リストの情報をSQL記述子域OUTDESCに取り込みます。
(12) INDESCに設定されている動的パラメタ指定の個数(COUNTの値)を取得します。
(13) INDESCに設定されているおのおのの動的パラメタ指定の情報(TYPE、LENGTH、OCTET_LENGTH、RECISION、SCALE、CHARACTER_SET_NAME、DATETIME_INTERVAL_CODE、DATETIME_INTERVAL_PRECISIONの値)を取得します。
(14) INDESCに設定されている動的パラメタ指定のデータ型を変更し、端末から読み込んだ動的パラメタ指定の値を設定します。
CHARACTER(n)、CHARACTER VARYING(n)をCHARACTER(14)に変更します。(nは文字列の長さ)
NATIONAL CHARACTER(n)、NATIONAL CHARACTER VARYING(n)をNATIONAL CHARACTER(10)に変更します。(nは文字列の長さ)
INTEGER、SMALLINTをINTEGERに変更します。
NUMERIC(p,q)、DECIMAL(p,q)、REAL、DOUBLE PRECISIONをDOUBLE PRECISIONに変更します。(pは精度、qは位取り)
DATE、TIME、TIMESTAMPおよびINTERVALをCHARACTER VARYING(19)に変更します。(nは文字列の長さ)
(15) OUTDESCに設定されている選択リストの個数(COUNTの値)を取得します。
(16) OUTDESCに設定されているおのおのの選択リストの情報(TYPE、LENGTH、OCTET_LENGTH、PRECISION、SCALE、CHARACTER_SET_NAME、DATETIME_INTERVAL_CODE、DATETIME_INTERVAL_PRECISIONの値)を取得します。
(17) OUTDESCに実行結果を取り出す相手指定のデータ型を設定します。
CHARACTER(n)、CHARACTER VARYING(n)をCHARACTER(14)に変更します。(nは文字列の長さ)
NATIONAL CHARACTER(n)、NATIONAL CHARACTER VARYING(n)をNATIONAL CHARACTER(10)に変更します。(nは文字列の長さ)
INTEGER、SMALLINTをINTEGERに変更します。
NUMERIC(p,q)、DECIMAL(p,q)、REAL、DOUBLE PRECISIONをDOUBLE PRECISIONに変更します。(pは精度、qは位取り)
DATE、TIME、TIMESTAMPおよびINTERVALをCHARACTER VARYING(19)に変更します。(nは文字列の長さ)
(18) (14)の値を使用して、カーソルCUR1をオープンします。
(19) 検索の結果データが見つからない場合にNOTFNDに進み、プログラムは終了します。
(20) カーソルCUR1の位置づけおよびデータの読み込みを行います。このとき、OUTDESCのDATAに実行結果の値が設定されます。
(21) SQL記述子域OUTDESCからNAMEとDATAの値を取得し、それぞれ相手指定のデータ型に一致したホスト変数に格納します。実行結果を端末に出力します。
(22) カーソルCUR1をクローズします。
(23) SQL記述子域INDESCを解放します。
(24) SQL記述子域OUTDESCを解放します。
(25) SQL文識別子STMIDに対応する被準備文を解放します。
(26) 現行のトランザクションを終了します。
(27) コネクションを切断します。
インクルードファイル“varfile.h”
/************************/
/* ホスト変数の定義開始 */
/************************/
    char      SQLSTATE[6];
    char      SQLMSG[256];
    VARCHAR   str[100];                        /*  SQL文変数              */
    short     vartype;                         /*  データ型               */  …(1)
    short     varleng;                         /*  文字数                 */  …(1)
    short     varolen;                         /*  バイト数               */  …(1)
    short     varprec;                         /*  精度                   */  …(1)
    short     varscal;                         /*  位取り                 */  …(1)
    char      varname[39];                     /*  列の名前               */  …(1)
    char      varchar[39];                     /*  文字セット名           */  …(1)
    short     vardcod;                         /*  日時,時間隔            */  …(1)
    short     vardpre;                         /*  時間隔精度             */  …(1)
    short     varicount;                       /*  動的パラメタ指定の数   */
    short     varocount;                       /*  選択リストの数         */
    short     i;                               /*  SQL記述子域のカウンタ  */
    VARCHAR   icdata[15];                      /*  CHARACTER型            */  …(2)
    VARCHAR CHARACTER SET IS NCHAR incdata[21];/*  NCHAR型                */  …(2)
    long      iidata;                          /*  真数型                 */  …(2)
    double    ifdata;                          /*  概数型                 */  …(2)
    VARCHAR   iddata[20];                      /*  日時,時間隔            */  …(2)
    char      ocdata[15];                      /*  CHARACTER型            */  …(3)
    char CHARACTER SET IS NCHAR  oncdata[21];  /*  NCHAR型                */  …(3)
    long      oidata;                          /*  真数型                 */  …(3)
    double    ofdata;                          /*  概数型                 */  …(3)
    VARCHAR   oddata[20];                      /*  日時,時間隔            */  …(3)
/************************/
/* ホスト変数の定義終了 */
/************************/(1) SQL記述子域
(2) 動的パラメタ指定
(3) 相手指定
備考.このアプリケーションの実行が正常に終了したときの出力例のイメージを以下に示します。ゴシック体の文字列が入力されたものとします。
実行する動的SELECT文を指定してください SELECT * FROM 在庫管理.在庫表 WHERE 在庫数量 < ?
在庫数量の値を指定してください 10 製品番号 -> 212 製品名 -> テレビ 在庫数量 -> 0 倉庫番号 -> 2 製品番号 -> 215 製品名 -> ビデオ 在庫数量 -> 5 倉庫番号 -> 2 製品番号 -> 226 製品名 -> 冷蔵庫 在庫数量 -> 8 倉庫番号 -> 1
1行のデータの取り出しを行う場合には、動的単一行SELECT文を準備して実行します。動的単一行SELECT文を実行するには、USING句を指定したEXECUTE文を使用します。SQL記述子域を使用して、動的パラメタ指定のある動的単一行SELECT文の指定例を以下に示します。なお、SQL記述子域を操作するSQL文の詳細については、“図4.4 被準備文の動的パラメタ指定値の設定手順”の例を参照してください。
端末から入力した動的単一行SELECT文の例です。端末から入力した動的パラメタ指定の値を探索条件としてデータを検索します。
                      :
     [端末から入力した動的単一行SELECT文をstrに格納]
                      :
EXEC SQL PREPARE STMID FROM :str;
EXEC SQL ALLOCATE DESCRIPTOR 'INDESC' WITH MAX 100;
EXEC SQL ALLOCATE DESCRIPTOR 'OUTDESC' WITH MAX 100;
EXEC SQL DESCRIBE INPUT STMID USING SQL DESCRIPTOR 'INDESC';
EXEC SQL DESCRIBE OUTPUT STMID USING SQL DESCRIPTOR 'OUTDESC';
EXEC SQL GET DESCRIPTOR 'INDESC' :icount = COUNT;
for( i = 1; i <= icount; i++ ) {
    EXEC SQL GET DESCRIPTOR 'INDESC' VALUE :i …
                      :
     [動的パラメタ指定の情報をSQL記述子域から取得]
                      :
    EXEC SQL SET DESCRIPTOR 'INDESC' VALUE :i …
                      :
     [端末から入力した動的パラメタ指定の値をSQL記述子域に設定]
                      :
}
EXEC SQL GET DESCRIPTOR 'OUTDESC' :ocount = COUNT;
for( i = 1; i <= ocount; i++ ) {
    EXEC SQL GET DESCRIPTOR 'OUTDESC' VALUE :i …
                      :
     [選択リストの情報をSQL記述子域から取得]
                      :
    EXEC SQL SET DESCRIPTOR 'OUTDESC' VALUE :i …
                      :
     [SQL記述子域の選択リストの情報を変更]
                      :
}
EXEC SQL EXECUTE STMID INTO SQL DESCRIPTOR 'OUTDESC' 
                       USING SQL DESCRIPTOR 'INDESC';
EXEC SQL GET DESCRIPTOR 'OUTDESC' VALUE :i …
                      :
     [実行結果の値の取得]
                      :
EXEC SQL DEALLOCATE DESCRIPTOR 'INDESC';
EXEC SQL DEALLOCATE DESCRIPTOR 'OUTDESC';
EXEC SQL DEALLOCATE PREPARE STMID;
                      :