Hitachi

ノンストップデータベース HiRDB Version 10 UAP開発ガイド


付録B.2 SQL記述領域の展開

SQL記述領域は,UAP内で宣言することで確保します。

ここでは,ソースプログラム中に展開するSQL記述領域の形,及び使用例を示します。

〈この項の構成〉

(1) SQL記述領域の展開形

(a) C言語の場合

C言語の場合のSQL記述領域の展開形を次に示します。

  struct {
    char   sqldaid[8];              /* 表ID           */
    long   sqldabc;                 /* 表の長さ          */
    short   sqln;                   /* SQLVARの配列の要素数 */
    short   sqld;                   /* ?パラメタ数,検索項目数  */
    struct  sqlvar{                 /* データ情報エリア      */
      unsigned char  sqldim;        /* 未使用           */
      unsigned char  sqlcod;        /* データコード        */
      short      sqlxdim;           /* 最大要素数         */
      union {      
        short      sqllen;          /* データ長          */
        struct {
          unsigned char  sqlprcsn;  /* 精度            */
          unsigned char  sqlscale;  /* 位取り           */
        } s_sqllen;
      } sqllen;
      short      sqlsys;            /* 未使用           */
      unsigned char  *sqldata;      /* データ領域アドレス     */
      short      *sqlind;           /* 標識変数アドレス      */
    } SQLVAR[n];※1
  } sqlda;※2

注※1 nは,必要な個数(1〜30000)を指定します。

注※2 構造体名称( 'sqlda' の部分)は,任意の文字列を指定してください。なお,構造体名称に'SQL'で始まる文字列は指定できません。

(b) COBOL言語の場合

COBOL言語の場合のSQL記述領域の展開形を次に示します。

  • Windows版,及び32ビットモードのUNIX版の場合

      01  USQLDA.※1
        02  USQLDAID         PIC  X(8)  VALUE  'SQLDA'.
        02  USQLDABC         PIC  S9(9)  COMP.
        02  USQLN            PIC  S9(4)  COMP.
        02  USQLD            PIC  S9(4)  COMP.
        02  USQLVAR   OCCURS  n  TIMES.※2
          03  USQLTYPE       PIC  S9(4)  COMP.
          03  FILLER  REDEFINES  USQLTYPE.
            04  USQLDIM      PIC  X(1).
            04  USQLCOD      PIC  X(1).
          03  USQLXDIM       PIC  S9(4)  COMP  VALUE  IS  1.
          03  USQLATTR.
            04  USQLLEN      PIC  S9(4)  COMP.
            04  FILLER  REDEFINES  USQLLEN.
              05  USQLPRCSN  PIC  X(1).
              05  USQLSCALE  PIC  X(1).
            04  USQLSYS      PIC  S9(4)  COMP.
          03  FILLER  REDEFINES  USQLATTR.
            04  USQLLOBLEN   PIC  S9(9)  COMP.
          03  USQLDATA  USAGE  IS  ADDRESS.
          03  USQLIND   USAGE  IS  ADDRESS.

    注※1 集合項目の名称('USQLDA'の部分)は,任意の名称を指定してください。なお,データ項目にSQLで始まる文字列は指定できません。

    注※2 nは必要な個数(1〜30000)を指定します。

  • 64ビットモードのUNIX版の場合

      01  USQLDA.※1
        02  USQLDAID         PIC  X(8)  VALUE  'SQLDA'.
        02  USQLDABC         PIC  S9(18)  COMP. ※3
        02  USQLN            PIC  S9(4)  COMP.
        02  USQLD            PIC  S9(4)  COMP.
        02  FILLER           PIC  X(4). ※3
        02  USQLVAR   OCCURS  n  TIMES.※2
          03  USQLTYPE       PIC  S9(4)  COMP.
          03  FILLER  REDEFINES  USQLTYPE.
            04  USQLDIM      PIC  X(1).
            04  USQLCOD      PIC  X(1).
          03  USQLXDIM       PIC  S9(4)  COMP  VALUE  IS  1.
          03  USQLATTR.
            04  USQLLEN      PIC  S9(4)  COMP.
            04  FILLER  REDEFINES  USQLLEN.
              05  USQLPRCSN  PIC  X(1).
              05  USQLSCALE  PIC  X(1).
            04  USQLSYS      PIC  S9(4)  COMP.
          03  FILLER  REDEFINES  USQLATTR.
            04  USQLLOBLEN   PIC  S9(9)  COMP.
          03  USQLDATA  USAGE  IS  ADDRESS.
          03  USQLIND   USAGE  IS  ADDRESS.

    注※1 集合項目の名称('USQLDA'の部分)は,任意の名称を指定してください。なお,データ項目にSQLで始まる文字列は指定できません。

    注※2 nは必要な個数(1〜30000)を指定します。

    注※3 Windows版,及び32ビットモードのUNIX版との違いを次に示します。

    ・USQLDABCのPICTURE句の内容

    ・USQLDとUSQLVARの間のFILLER項目の有無

(2) SQL記述領域の使用例

(a) SQL記述領域を使用するための宣言,及び領域の確保

SQL記述領域は,UAP内で宣言し,確保します。

(b) 検索項目情報の取得

検索項目情報の取得例を次に示します。

EXEC SQL BEGIN DECLARE SECTION;   .................... 1
struct{   ............................................ 1
long  cmd_len;   .................................... 1
char  cmd_data[1000];   .............................. 1
}XCMND;   ............................................ 1
EXEC SQL END DECLARE SECTION;   ...................... 1
XCMND.cmd_len=(long)sprintf(XCMND.cmd_data,
                 "SELECT*FROM ZAIKO WHERE GNO=1")   .. 2
EXEC SQL WHENEVER SQLERROR GO TO :RERROR;   .......... 3
EXEC SQL PREPARE ST1 FROM :XCMND;   .................. 4
EXEC SQL DESCRIBE ST1 INTO :DAREA;   ................. 5

注1 DESCRIBE文を実行すると,SQLD領域に2進数の0,又は検索項目が設定されます。

  • 0前処理したSQLがSELECT文以外の場合

  • 検索項目:前処理したSQLがSELECT文の場合

注2 各検索項目のデータコードがSQLCODに,データの定義長がSQLLENに,最大要素数がSQLXDIMにそれぞれ設定されます。

注※ 64ビットモードの場合は,intとなります。

<説明>
  1. SQL格納用の埋込み変数(XCMND)を宣言します。

  2. SQL文を変数(XCMND)に設定します。

  3. SQL実行後のエラーに対する処置を指定します。

  4. 変数XCMNDとして指定したSQLを前処理して,SQL文識別子(ST1)を付けます。

  5. SQL(ST1)の検索項目情報をSQL記述領域(DAREA)に取得します。

(c) 受取り領域を動的に決定した検索結果の取出し

DESCRIBE文で得た情報を基に割り当てた領域に検索結果を取り出す場合の例を次に示します。

for(n=0;n<DAREA.sqld;n++){   ...................................... 1
    DAREA.SQLVAR[n].sqldata=(unsigned char *)&(X_INT_DATA[n]);   .. 1
    DAREA.SQLVAR[n].sqlind=&(X_IND[n]);   ......................... 1
}   ................................................................1
EXEC SQL DECLARE CR1 CURSOR FROM ST1;   ........................... 2
EXEC SQL OPEN CR1   ............................................... 3
EXEC SQL WHENEVER NOT FOUND GO TO:FEND;   ......................... 4
for(;;){   ........................................................ 5
    EXEC SQL FETCH CR1 USING DESCRIPTOR:DAREA   ................... 5
                    :   ........................................... 5,6
}   ............................................................... 5
    EXEC SQL WHENEVER NOT FOUND CONTINUE;   ....................... 7
FEND:EXEC SQL CLOSE CR1;   ........................................ 8

注 FETCH文を実行するまでに,次に示す情報をDAREAに設定してください。

  • SQLVAR配列の大きさ(SQLN)

  • 検索結果を受け取る領域の個数(SQLD):DESCRIBE文を実行すると設定される。

  • 受取り領域のデータ型(SQLCOD):DESCRIBE文を実行すると設定される。

  • 受取り領域のデータ長(SQLLEN):DESCRIBE文を実行すると設定される。

<説明>
  1. 割り当てた領域の番地をSQL記述領域(DAREA)に設定する。

  2. SQL文識別子(ST1)に対してカーソル(CR1)を宣言する。

  3. カーソル(CR1)を開く。

  4. 検索終了時の処理(FENDへの分岐)を指定する。

  5. カーソル(CR1)を次の行に位置付け,その行をSQL記述領域(DAREA)で指定した領域に取り出す。

  6. 編集・出力など検索結果に対する処理を指定する。

  7. 検索終了時の処置を無効にする。

  8. カーソル(CR1)を閉じる。

(d) ?パラメタに対する値を指定するためのデータ領域の動的決定

動的に指定された表にデータを挿入する場合の例を次に示します。

char TNAME[30];   ............................................... 1
scanf("%S",TNAME);   ............................................ 2
XCMND.cmd_len=(long)sprint(XCMND.cmd_data,
                    "SELECT * FROM %S",TNAME);   ................ 3
 
EXEC SQL PREPARE ST1 FROM:XCMND;   .............................. 3
 
EXEC SQL DESCRIBE ST1 INTO:DAREA;   ............................. 3
         :   .................................................... 4
for(n=0;n<DAREA.sqld;n++){   .................................... 5
DAREA.SQLVAR[n].sqldata=(unsigned char *)&(X_INT_DATA[n]);   .... 5
DAREA.SQLVAR[n].sqlind=&(X_IND[n]);   ........................... 5
}   ............................................................. 3
XCMND.cmd_len=(long)sprit(XCMND.cmd_data,
              "INSERT INTO %S VALUES(?,…,?)",TNAME);   ......... 6
 EXEC SQL PREPARE ST2 FROM:XCMND;   ............................. 7
for(;;){   ...................................................... 8
   〔挿入データの入力(データがない場合,IENDに分岐)〕;   .. 8
   〔データ領域,標識変数領域にデータを挿入〕;   ................ 8
  EXEC SQL EXECUTE ST2 USING DESCRIPTOR:DAREA;   ................ 8
}   ............................................................. 8
IEND:

注※ 64ビットモードの場合は,intとなります。

<説明>
  1. 表名を格納する変数(TNAME)を宣言します。

  2. 入力データから変数(TNAME)に表名を読み込みます。

  3. ?パラメタの個数,及び各?パラメタに対するデータ領域のデータ型,データ長,最大要素数として,2で指定された表の列数,各列のデータ型,データの定義長,最大要素数をDESCRIBE文を利用して,SQL記述領域(DAREA)に設定します。

  4. 各?パラメタに対するデータ領域を確保して割り当てます。

  5. 割り当てた領域の番地をSQL記述領域(DAREA)に設定します。

  6. 指定された表にデータを挿入するためのINSERT文を生成します。

  7. XCMND中のINSERT文を前処理して,SQL文識別子(ST2)を付けます。

  8. 挿入するデータがない間,行単位に挿入データの入力,データ領域への設定,EXECUTE文による実行を繰り返します。

(e) FETCH文でDECIMAL型のデータを検索する場合の例

FETCH文でDECIMAL型のデータを検索する例を次に示します。

  1. データ領域,及び標識変数の宣言

    EXEC  SQL  BEGIN  DECLARE  SECTION ;
     
       SQL TYPE IS DECIMAL(20,0) xdec1 ;     /* データ領域       */
       short                     xdec1_i ;   /* 標識変数         */
     
    EXEC  SQL  END  DECLARE  SECTION ;
  2. SQL記述領域の設定

    PDSQLCOD(usrsqlda, 2)=PDSQL_DECIMAL_I ; /* データコード設定  */
     
      PDSQLPRCSN(usrsqlda, 2)=20          ; /* 精度の設定        */
      PDSQLSCALE(usrsqlda, 2)= 0          ; /* 位取りの設定      */
      PDSQLDATA(usrsqlda, 2)=(void*)xdec1 ; /* 埋込み変数アドレス*/
                                            /* 設定              */
      PDSQLXDIM(usrsqlda, 2)=1;             /* 繰返し列ではない  */
     
    PDSQLIND(usrsqlda, 2)=(void*)&xdec1_i ; /* 標識変数アドレス  */
                                            /* 設定              */

(3) SQL記述領域の展開方法

SQL記述領域の展開方法を次の表に示します。

表B‒4 SQL記述領域の展開方法

言語

インクルードファイルを利用する

ユーザが直接記述する

C

#include <pdbsqlda.h>

PDUSRSQLDA(n) usrsqlda;

SQL記述領域の展開形を直接コーディングします。

COBOL

COPY SQLDA

[ REPLACING 256 BY n ].

SQL記述領域の展開形を直接コーディングします。必ず01レベルから記述してください。

注※ 64ビットモードの場合はSQLDAをSQLDA64に変更してください。

COBOL言語の場合のSQL記述領域でパラメタを指定した場合の記述例を次に示します。

EXEC  SQL
    BEGIN  DECLARE  SECTION
END   EXEC
01  IN-CHR1  PIC  X(15).
01  IN-IND1  PIC  S9(4)  COMP.
EXEC  SQL
    END  DECLARE  SECTION
END-EXEC
COPY  SQLDA.
         :
COMPUTE  USQLDABC=32
COMPUTE  USQLN=1
COMPUTE  USQLD=1
COMPUTE  USQLDATA(1)=FUNCTION  ADDR(IN-CHR1)
MOVE  SQLCNST0    TO USQLDIM(1)
MOVE  SQLDCOD197  TO USQLCOD(1)
COMPUTE  USQLXDIM(1)=1
COMPUTE  USQLLEN(1)=15
COMPUTE  USQLIND(1)=FUNCTION  ADDR(IN-INT1)
EXEC  SQL
    EXECUTE  ST1  USING  DESCRIPTOR  :USQLDA
END-EXEC

(4) SQL記述領域操作用マクロ

C言語では,SQLDAの宣言,及び値の設定・参照用に各種のマクロが定義されています。これらのマクロは専用のヘッダファイル(pdbsqlda.h)をUAPにインクルードすることで使用できます。SQL記述領域操作用マクロを次の表に示します。

表B‒5 SQL記述領域操作用マクロ

マクロ名

機能

PDUSRSQLDA(m)

ユーザ用SQLDAを宣言します。

PDSETSIZE(usrsqlda,m)

SQLDAのサイズを設定します。

PDSQLN(usrsqlda)

?パラメタ数を設定します。

PDSQLD(usrsqlda)

?パラメタ,検索項目数を設定・参照します。

PDSQLCOD(usrsqlda,n)

データコードを設定・参照します。

PDSQLLEN(usrsqlda,n)

?パラメタの実長を設定・参照します(BLOBと10進数以外)。

PDSQLPRCSN(usrsqlda,n)

精度を設定・参照します(10進数だけ)。

PDSQLSCALE(usrsqlda,n)

位取りを設定・参照します(10進数だけ)。

PDSQLDATA(usrsqlda,n)

データ領域のアドレスを設定します。

PDSQLIND(usrsqlda,n)

標識変数アドレスを設定します。

PDSQLLOBLEN(usrsqlda,n)

BLOBのデータ長を設定・参照します。

PDSQLDIM(usrsqldata,n)

未使用領域の値を設定・参照します。

PDSQLXDIM(usrsqldata,n)

繰り返し構造の最大要素数を設定・参照します。

PDSQLSYS(usrsqldata,n)

繰り返し構造又は配列構造の可変長の文字列型のギャップを含む1要素の長さを設定します。

(凡例)

usrsqlda:ユーザ定義のSQL記述領域名。任意の値を指定してください。

m:?パラメタの個数(1〜30000)

n:設定,又は参照する?パラメタの番号(0〜29999)

データ型指定用マクロを次の表に示します。

表B‒6 データ型指定用マクロ

マクロ名

標識変数

対応するデータ型

PDSQL_FLOAT

なし

FLOAT

PDSQL_FLOAT_I

あり

PDSQL_SMALLFLT

なし

SMALLFLT

PDSQL_SMALLFLT_I

あり

PDSQL_DECIMAL

なし

DECIMAL

PDSQL_DECIMAL_I

あり

PDSQL_INTEGER

なし

INTEGER

PDSQL_INTEGER_I

あり

PDSQL_SMALLINT

なし

SMALLINT

PDSQL_SMALLINT_I

あり

PDSQL_VARCHAR

なし

VARCHAR

PDSQL_VARCHAR_I

あり

PDSQL_CHAR

なし

CHAR

PDSQL_CHAR_I

あり

PDSQL_NVARCHAR

なし

NVARCHAR

PDSQL_NVARCHAR_I

あり

PDSQL_NCHAR

なし

NCHAR

PDSQL_NCHAR_I

あり

PDSQL_MVARCHAR

なし

MVARCHAR

PDSQL_MVARCHAR_I

あり

PDSQL_MCHAR

なし

MCHAR

PDSQL_MCHAR_I

あり

PDSQL_DATE

なし

DATE

PDSQL_DATE_I

あり

PDSQL_TIME

なし

TIME

PDSQL_TIME_I

あり

PDSQL_YEARTODAY

なし

INTERVAL YEAR TO DAY

PDSQL_YEARTODAY_I

あり

PDSQL_HOURTOSEC

なし

INTERVAL HOUR TO SECOND

PDSQL_HOURTOSEC_I

あり

PDSQL_ROW

なし

ROW

PDSQL_ROW_I

あり

PDSQL_BLOB

なし

BLOB

PDSQL_BLOB_I

あり

PDSQL_TIMESTAMP

なし

TIMESTAMP

PDSQL_TIMESTAMP_I

あり

PDSQL_BINARY

なし

BINARY

PDSQL_BINARY_I

あり

PDSQL_BLOB_LOC

なし

BLOB位置付け子

PDSQL_BLOB_LOC_I

あり

PDSQL_BINARY_LOC

なし

BINARY位置付け子

PDSQL_BINARY_LOC_I

あり

PDSQL_CVARCHAR

なし

C言語用のVARCHAR

PDSQL_CVARCHAR_I

あり

C言語の場合のSQL記述領域でパラメタを指定した場合の記述例を次に示します。

#include <pdbsqlda.h>              /* ヘッダファイルのインクルード */
  
EXEC  SQL  BEGIN  DECLARE  SECTION ;
short  xint1 ;
char   xchr1[16] ;
EXEC  SQL  END  DECLARE  SECTION ;
PDUSRSQLDA(2)  usrsqlda ;                /* SQL記述領域の宣言  */
          :
ClearSqlda(2) ;                          /* SQL記述領域のクリア  */
PDSQLCOD(usrsqlda, 0)=PDSQL_SMALLINT ;   /* データコード設定    */
PDSQLLEN(usrsqlda, 0)=sizeof(short) ;    /* データ長設定      */
PDSQLDATA(usrsqlda, 0)=(void*)&xint ;    /* 埋込み変数アドレス設定 */
PDSQLIND(usrsqlda, 0)=NULL ;             /* 標識変数アドレス設定  */
PDSQLCOD(usrsqlda, 1)=PDSQL_CHAR ;       /* データコード設定    */
PDSQLLEN(usrsqlda, 1)=sizeof(xchar)-1 ;  /* データ長設定      */
PDSQLDATA(usrsqlda, 1)=(void*)xchr ;     /* 埋込み変数アドレス設定 */
PDSQLIND(usrsqlda, 1)=NULL ;             /* 標識変数アドレス設定  */
  
EXEC  SQL
    EXECUTE  ST1  USING  DESCRIPTOR  :usrsqlda ;
          :
/*******************************************************************/
/* SQL記述領域初期設定                                             */
/*******************************************************************/
void ClearSqlda(
short num)
{
  PDSETSIZE(usrsqlda, 2) ;             /* SQL記述領域のサイズ設定 */
  PDSQLN(usrsqlda) = num ;             /* 配列サイズの上限設定   */
  PDSQLD(usrsqlda) = num ;             /* ?パラメタ数の設定    */
  while(num-->0) {
    PDSQLDATA(usrsqlda, num) = NULL ; /* 埋込み変数のクリア     */
    PDSQLIND(usrsqlda, num) = NULL ;  /* 標識変数のクリア      */
    PDSQLDIM(usrsqlda, num) = 0 ;     /* 未使用領域のクリア     */
    PDSQLXDIM(usrsqlda, num) = 1 ; /* 繰り返し構造の要素数クリア   */
    PDSQLSYS(usrsqlda, num) = 0 ;  /* 配列,繰り返し構造の要素サイズ */
    PDSQLCOD(usrsqlda, num) = 0 ;     /* データコードクリア      */
    PDSQLLEN(usrsqlda, num) = 0 ;     /* データ長クリア        */
  }
  return ;
}

(5) 繰返し列の展開形式

繰返し列の埋込み変数は,コンパイル時にマクロ定義によって表B-7に示す構造体が展開されます。ここでは,C言語の場合について説明します。

繰返し列操作用のマクロは,展開される構造体のメンバを使用して繰返し列の要素を参照します。

ユーザが領域を確保して,SQL記述領域にアドレスを直接設定する場合は,領域を語境界に割り当てる必要があります。FLOAT ARRAYの場合は,語境界調整のために空領域が明示的に含まれていますが,SQL記述領域に設定するアドレスは,空領域分を考慮して設定する必要があります。

なお,これらの展開形式は,上記の領域確保での境界調整,及び構造体のサイズを取得する場合にだけ指定してください。埋込み変数として繰返し列を指定する場合は,展開形式を指定しないで,「SQLのデータ型とデータ記述」のマクロを使用してください。

表B‒7 繰返し列の展開形式

SQLのデータ型

マクロ名

展開形式

SMALL INT ARRAY[m]

PD_MV_SINT(m)

struct {

long mcnt;

short data[m];

}

INTTGER ARRAY[m]

PD_MV_INT(m)

struct{

long mcnt

long data[m];

}

SMALL FLT ARRAY[m]

PD_MV_SFLT(m)

struct{

long mcnt;

float data[m];

}

FLOAT ARRAY[m]

PD_MV_FLT(m)

struct{

union {

double resv1;

struct {

long resv2;

long mcnt;

}mcnt_dmy2;

} mcnt_dmy1;

double data[m];

}

CHAR(n) ARRAY[m]

PD_MV_CHAR(m, n)

struct {

long mcnt;

char data[m][(n)+1];

}

NCHAR(n) ARRAY[m]

PD_MV_NCHAR(m, n)

struct {

long mcnt;

char data[m][2*(n)+1];

}

VARCHAR(n) ARRAY[m]

PD_MV_VCHAR(m, n)

struct {

long mcnt;

struct {

short len;

char str[n];

} data[m];

}

PD_MV_CVCHAR(m, n)

struct {

long mcnt;

char data[m][(n)+1];

}

NVARCHAR(n) ARRAY[m]

PD_MV_NVCHAR(m, n)

struct {

long mcnt;

struct {

short len;

char str[2*(n)+1];

} data[m];

}

DECIMAL

〔(p〔,s〕)〕ARRAY[m]

PD_MV_DEC(m, p, s)

struct {

long mcnt;

unsigned char data[m][(p)/2+1];

}