付録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となります。
- <説明>
-
-
SQL格納用の埋込み変数(XCMND)を宣言します。
-
SQL文を変数(XCMND)に設定します。
-
SQL実行後のエラーに対する処置を指定します。
-
変数XCMNDとして指定したSQLを前処理して,SQL文識別子(ST1)を付けます。
-
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文を実行すると設定される。
- <説明>
-
-
割り当てた領域の番地をSQL記述領域(DAREA)に設定する。
-
SQL文識別子(ST1)に対してカーソル(CR1)を宣言する。
-
カーソル(CR1)を開く。
-
検索終了時の処理(FENDへの分岐)を指定する。
-
カーソル(CR1)を次の行に位置付け,その行をSQL記述領域(DAREA)で指定した領域に取り出す。
-
編集・出力など検索結果に対する処理を指定する。
-
検索終了時の処置を無効にする。
-
カーソル(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となります。
- <説明>
-
-
表名を格納する変数(TNAME)を宣言します。
-
入力データから変数(TNAME)に表名を読み込みます。
-
?パラメタの個数,及び各?パラメタに対するデータ領域のデータ型,データ長,最大要素数として,2で指定された表の列数,各列のデータ型,データ長,最大要素数をDESCRIBE文を利用して,SQL記述領域(DAREA)に設定します。
-
各?パラメタに対するデータ領域を確保して割り当てます。
-
割り当てた領域の番地をSQL記述領域(DAREA)に設定します。
-
指定された表にデータを挿入するためのINSERT文を生成します。
-
XCMND中のINSERT文を前処理して,SQL文識別子(ST2)を付けます。
-
挿入するデータがない間,行単位に挿入データの入力,データ領域への設定,EXECUTE文による実行を繰り返します。
-
(e) FETCH文でDECIMAL型のデータを検索する場合の例
FETCH文でDECIMAL型のデータを検索する例を次に示します。
-
データ領域,及び標識変数の宣言
EXEC SQL BEGIN DECLARE SECTION ; SQL TYPE IS DECIMAL(20,0) xdec1 ; /* データ領域 */ short xdec1_i ; /* 標識変数 */ EXEC SQL END DECLARE SECTION ;
-
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記述領域の展開方法を次の表に示します。
言語 |
インクルードファイルを利用する |
ユーザが直接記述する |
---|---|---|
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記述領域操作用マクロを次の表に示します。
マクロ名 |
機能 |
---|---|
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)
データ型指定用マクロを次の表に示します。
マクロ名 |
標識変数 |
対応するデータ型 |
---|---|---|
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のデータ型とデータ記述」のマクロを使用してください。
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]; } |