第3章 アプリケーションの作成
3.1 SQL 埋込み C プログラムの作成方法
3.1.9 構造体として宣言したホスト変数の使用方法
:
ret = get_data( image, 5 ); …… (2) :
return 1;
}
short get_data(
void *image_data;
short number;
{
EXEC SQL BEGIN DECLARE SECTION;
char SQLSTATE[6];
char SQLMSG[256];
:
SQL TYPE IS BLOB *image;
short datano;
:
EXEC SQL END DECLARE SECTION;
:
image = (struct image_SQLBLOB *)image_data; …… (3) image->image_length = 10240; …… (4) datano = number;
: /* データの取得 */
EXEC SQL SELECT IMAGE …… (5) INTO :image
FROM SCH01.TBL01 WHERE DATANO = :datano;
: return 0;
}
(1) データ取得関数に指定するデータ領域を取得します。
(2) データ取得関数を呼び出します。
(3) ホスト変数に領域アドレスを設定します。
(4) ホスト変数の領域長を設定します。
(5) データを取得します。
・
単一行SELECT文のINTO句に指定する場合は、選択リストの数と構造体のメンバの個数は同じでなければなりませ ん。また、構造体のメンバの順序は、選択リストに指定されている列の順序に対応します。・
FETCH文のINTO句に指定する場合は、カーソル宣言で指定した問合せ指定の選択リストの数と構造体のメンバの個数は同じでなければなりません。また、構造体のメンバの順序は、選択リストに指定されている列の順序に対応し ます。
・
選択リストに“*”が指定された場合は、FROM句で指定した順に各表の各列のすべてに対応したメンバを定義する 必要があります。・
EXECUTE文の結果USING句に指定する場合は、被準備文である動的単一行SELECT文の相手指定の個数と構造体のメンバの個数は同じでなければなりません。また、構造体のメンバの順序は、被準備文の相手指定の順序に 対応します。
・
EXECUTE文のパラメタUSING句に指定する場合は、被準備文の動的パラメタ指定の個数と構造体のメンバの個数は同じでなければなりません。また、構造体のメンバの順序は、被準備文の動的パラメタの順序に対応します。
・
それぞれの列に対応するメンバの型は、列の型に対して指定可能でなければなりません。・
構造体のメンバを指定する場合は、メンバの型で宣言されたホスト変数と同様に使用することができます。・
構造体を定義する場合に、メンバとして構造体を指定することはできません。構造体ホスト変数の使用方法
データを構造体ホスト変数で取得する例
#include <stdio.h>
#include <string.h>
EXEC SQL BEGIN DECLARE SECTION char SQLSTATE[6];
char SQLMSG[256];
:
struct { …… (1) long num;
char name[21];
char atta[41];
short year;
} data;
short number;
:
EXEC SQL END DECLARE SECTION;
short main() {
: /* データの取得 */
EXEC SQL SELECT * INTO :data …… (2) FROM SCH01.TBL01
WHERE NUMBER = :number;
return 1;
}
(1) 構造体型のホスト変数を宣言します。
(2) 該当するデータを取得します。
ポインタ宣言した構造体変数を使用する例
short get_10_data( void * );
short set_10_data( void * );
EXEC SQL BEGIN DECLARE SECTION;
struct _tbl { …… (1)
short number;
SQL TYPE IS BLOB(10K) image1;
SQL TYPE IS BLOB(10K) image2;
};
EXEC SQL END DECLARE SECTION;
EXEC SQL BEGIN DECLARE SECTION;
char SQLSTATE[6];
char SQLMSG[256];
EXEC SQL END DECLARE SECTION;
short main() {
:
struct _tbl *buff;
:
buff = (struct _tbl *)malloc( sizeof( struct _tbl ) ); …… (2) memset(buff, 0x00, sizeof(struct _tbl));
:
get_10_data( (void *)buff ); …… (3) :
set_10_data( (void *)buff ); …… (4) :
return 1;
}
short get_10_data( void *data0 ) {
EXEC SQL BEGIN DECLARE SECTION;
struct _tbl *outdata; …… (5) EXEC SQL END DECLARE SECTION;
:
outdata = (struct _tbl *)data0; …… (6) EXEC SQL SELECT DATANO,IMAGE1,IMAGE2 INTO :outdata …… (7) FROM SCH01.TBL01;
: return 0;
}
short set_10_data( void *data0 ) {
EXEC SQL BEGIN DECLARE SECTION;
struct _tbl *indata; …… (8) EXEC SQL END DECLARE SECTION;
:
indata = (struct _tbl *)data0; …… (9) EXEC SQL UPDATE SCH01.TBL01 SET IMAGE = :indata->image1 …… (10) WHERE DATANO = :indata->number;
: return 0;
}
(1) 構造体の型を宣言します。
(2) 領域を取得します。
(3) データ領域をデータ取得関数のパラメタに設定し、関数を呼びます。
(4) データ領域をデータ設定関数のパラメタに設定し、関数を呼びます。
(5) 構造体型のホスト変数を定義します。
(6) ホスト変数に領域のアドレスを設定します。
(7) データを取得します。
(8) 構造体型のホスト変数を定義します。
(9) ホスト変数に領域のアドレスを設定します。
(10) データを更新します。
標識変数の使用方法
構造体ホスト変数を使用する場合、標識変数は以下のようになります。
構造体標識変数
short型のメンバを持ち、構造体として宣言した変数を、標識変数として指定します。
-
メンバはすべてshort型でなければなりません。-
メンバの数はホスト変数のメンバの数と同じでなければなりません。-
標識変数のメンバの順序は、ホスト変数のメンバの順序に対応します。:
EXEC SQL BEGIN DECLARE SECTION;
char SQLSTATE[6];
char SQLMSG[256];
struct {
long col1; (1) char col2[21]; (2) char col3[41]; (3) short col4; (4) } data;
struct {
short ind1; (5) short ind2; (6) short ind3; (7) short ind4; (8) } indi;
EXEC SQL END DECLARE SECTION;
:
EXEC SQL SELECT COL01, COL02, COL03, COL04 INTO :data :indi
FROM SCH01.TBL01 WHERE DATANO = 1;
:
(1)のメンバに対応する標識変数は(5)になります。
同様に(2)-(6)、(3)-(7)、(4)-(8)が対応します。
配列指定の標識変数
short型の配列指定の変数1つをメンバとする構造体型の変数を標識変数とし、配列の要素数はホスト変数のメンバ
数と同じとします。
-
メンバはshort型でなければなりません。-
メンバの配列数はホスト変数のメンバの数と同じでなければなりません。-
標識変数の配列の順序は、ホスト変数のメンバの順序に対応します。:
EXEC SQL BEGIN DECLARE SECTION;
char SQLSTATE[6];
char SQLMSG[256];
struct {
long col1; (1) char col2[21]; (2) char col3[41]; (3) short col4; (4)
} data;
struct {
short ind[4]; (5) } indi;
EXEC SQL END DECLARE SECTION;
:
EXEC SQL SELECT COL01, COL02, COL03, COL04 INTO :data :indi
FROM SCH01.TBL01 WHERE DATANO = 1;
:
(1)のメンバに対応する標識変数は(5)のindi.ind[0]です。
同様に(2)-indi.ind[1]、(3)-indi.ind[2]、(4)-indi.ind[3]が対応します。
複数行の一括挿入
配列指定された構造体型のホスト変数または、構造体型のホスト変数のポインタを使用することで、INSERT文により複 数行のデータを一括挿入することができます。
複数行の一括挿入:(1)配列指定された構造体型を利用 以下の方法で、複数行を一括挿入する例を示します。
-
挿入データとして、配列指定された構造体型のホスト変数を指定-
構造体のメンバには配列指定を含めることはできません。ただし、文字列型の1次元配列は指定可能です。-
挿入する行数をINSERT文のFOR句に指定します。-
標識変数を指定することはできません。:
EXEC SQL BEGIN DECLARE SECTION;
char SQLSTATE[6];
char SQLMSG[256];
struct { short col1;
short col2;
VARCHAR col3[10];
VARCHAR col4[10];
} data[5];
short rowcount;
EXEC SQL END DECLARE SECTION;
: data[0].col1 = 1;
data[0].col2 = 100;
strcpy( data[0].col3.sqlvar, "KANAGAWA" );
data[0].col3.sqllen = strlen( data[0].col3.sqlvar );
strcpy( data[0].col4.sqlvar, "ODAWARA" );
data[0].col4.sqllen = strlen( data[0].col4.sqlvar );
data[1].col1 = 2;
data[1].col2 = 200;
strcpy( data[1].col3.sqlvar, "SHIZUOKA" );
data[1].col3.sqllen = strlen( data[1].col3.sqlvar );
strcpy( data[1].col4.sqlvar, "MISHIMA" );
data[1].col4.sqllen = strlen( data[1].col4.sqlvar );
: data[4].col1 = 5;
data[4].col2 = 500;
strcpy( data[4].col3.sqlvar, "KANAGAWA" );
data[4].col3.sqllen = strlen( data[4].col3.sqlvar );
strcpy( data[4].col4.sqlvar, "YOKOHAMA" );
data[4].col4.sqllen = strlen( data[4].col4.sqlvar );
rowcount = 5;
EXEC SQL INSERT INTO SCH1.TBL1( COL01, COL02, COL03, COL04 ) VALUES( :data ) FOR :rowcount;
:
複数行の一括挿入:(2)構造体のポインタ型を利用 以下の方法で、複数行を一括挿入する例を示します。
-
挿入データとして、構造体のポインタ型のホスト変数を指定-
構造体のメンバには配列指定を含めることはできません。ただし、文字列型の1次元配列は指定可能です。-
挿入する行数をINSERT文のFOR句に指定します。-
標識変数を指定することはできません。-
INSERT文のFOR句に指定した値と実際のデータ個数を必ず一致させてください。-
INSERT文のVALUES句にデータのポインタを正しく設定してください。:
EXEC SQL BEGIN DECLARE SECTION;
struct _tbl{
short col1;
short col2;
CHAR col3[5];
CHAR col4[5];
};
char SQLSTATE[6];
char SQLMSG[256];
EXEC SQL END DECLARE SECTION;
short insert_dat(struct _tbl *, short );
int main() {
short i, data_count;
struct _tbl *data;
data_count = 3;
data = (struct _tbl *) malloc(sizeof(struct _tbl)*data_count);
memset(data, 0x00, sizeof(struct _tbl)*data_count);
data[0].col1 = 1;
data[0].col2 = 100;
strcpy( data[0].col3, "AAAA" );
strcpy( data[0].col4, "BBBB" );
data[1].col1 = 2;
data[1].col2 = 200;
strcpy( data[1].col3, "CCCC" );
strcpy( data[1].col4, "DDDD" );
data[2].col1 = 3;
data[2].col2 = 300;
strcpy( data[2].col3, "EEEE" );
strcpy( data[2].col4, "FFFF" );
insert_dat(data, data_count);
return 0;
}
short insert_dat( struct _tbl *data, short data_count) {
EXEC SQL BEGIN DECLARE SECTION;
struct _tbl *indata;
short rowcount;
EXEC SQL END DECLARE SECTION;
indata = data;
rowcount = data_count;
EXEC SQL CONNECT TO DEFAULT;
EXEC SQL DELETE FROM ST1.TBL4;
EXEC SQL INSERT INTO ST1.TBL4(COL01, COL02, COL03, COL04) VALUES (:indata) FOR :rowcount;
EXEC SQL COMMIT WORK;
EXEC SQL DISCONNECT ALL;
return 0;
}