7.2.2 プログラム例題
C言語による埋込み型UAPのプログラム例題を示します。
なお,SQLの文法の詳細については,マニュアル「HiRDB SQLリファレンス」を参照してください。
(1) 基本的な操作の例
(a) PADチャート
プログラム例題1のPADチャートを次の図に示します。
|
|
|
|
(b) コーディング例
プログラム例題1のコーディング例を次に示します。
1 #include <string.h>
2 #include <stdlib.h>
3
4 #define MAXCOLUMN 80 /* max column in one line */
5 #define INFILE "inputf1" /* input data file name */
6
7 /* declare functions */
8 void abnormalend();
9 void connecterror();
10
11 FILE *input = NULL;
12
13 main()
14 {
15 /* input data */
16 char indata[MAXCOLUMN + 1];
17
18 char in_userid[31];
19 char in_passwd[31];
20 char in_kubun;
21 char in_scode[5];
22 char in_sname[17];
23 char in_col[3];
24 int in_tanka;
25 int in_gryo;
26 char in_okubun;
27
28 /* variables for SQL */
29 EXEC SQL BEGIN DECLARE SECTION; 1
30 char xuserid[31]; 1
31 char xpasswd[31]; 1
32 char xscode[5]; 1
33 char xsname[17]; 1
34 char xcol[3]; 1
35 long xtanka; 1
36 long xgryo; 1
37 EXEC SQL END DECLARE SECTION; 1
38
39 /* input file open */ 2
40 input = fopen(INFILE, "r"); 2
41 if (input == NULL) { 2
42 /* input file open error */ 2
43 fprintf(stderr, "can't open %s.", INFILE); 2
44 goto FIN; 2
45 } 2
46 2
47 /* get userid/passwd */ 2
48 fgets(indata, 81, input); 2
49 sscanf(indata, "%30s %30s", xuserid, xpasswd); 2
50 if (feof(input)) { 2
51 fprintf(stderr, "*** error *** no data for connect ***"); 2
52 goto FIN; 2
53 } 2
54 printf("connect start,\n"); 2
55 EXEC SQL WHENEVER SQLERROR PERFORM connecterror; (a) 2
56 EXEC SQL CONNECT USER :xuserid USING :xpasswd; (b) 2
57 printf("connected,\n"); 2
58
59 /* read data from inputfile */
60 EXEC SQL WHENEVER SQLERROR PERFORM abnormalend;
61 fgets(indata, MAXCOLUMN, input);
62
63 while (!feof(input)) {
64 sscanf(indata, "%c %4s %16s %2s %8d %8d %c",
65 &in_kubun, in_scode, in_sname, in_col,
66 &in_tanka, &in_gryo, &in_okubun);
67 switch (in_kubun) {
68 case 'I':
69 strncpy(xscode, in_scode, 4);
70 strncpy(xsname, in_sname, 8);
71 strncpy(xcol, in_col, 2);
72 xtanka = in_tanka;
73 xgryo = in_gryo;
74 EXEC SQL 3
75 INSERT INTO ZAIKO(SCODE,SNAME,COL,TANKA,ZSURYO) 3
76 VALUES(:xscode,:xsname,:xcol,:xtanka,:xgryo); 3
77 break;
78 case 'U':
79 strncpy(xscode, in_scode, 4); 4
80 xgryo = in_gryo; 4
81 if (in_okubun == '1') { 4
82 EXEC SQL (a) 4
83 UPDATE ZAIKO SET ZSURYO=ZSURYO+:xgryo (a) 4
84 WHERE SCODE=:xscode; (a) 4
88 } else { 4
86 EXEC SQL (b) 4
87 UPDATE ZAIKO SET ZSURYO=ZSURYO-:xgryo (b) 4
88 WHERE SCODE=:xscode; (b) 4
89 }
90 break;
91 case 'D':
92 strncpy(xscode, in_scode, 4);
93 EXEC SQL 5
94 DELETE FROM ZAIKO WHERE SCODE=:xscode; 5
95 break;
96 }
97 fgets(indata, MAXCOLUMN, input);
98 }
99
100 /* print zaiko list */
101 EXEC SQL 6
102 DECLARE CR1 CURSOR FOR 6
103 SELECT SCODE,SNAME,COL,TANKA,ZSURYO FROM ZAIKO; 6
104 EXEC SQL OPEN CR1; 7
105
106 /* print midashi */
107 printf("\n\n");
108 printf(" ***** 在庫表 リスト *****\n\n");
109 printf(" 商品コート゛ 商品名 色 単価 現在庫量\n");
110 printf(" ---- ---------------- -- -------- --------\n");
111
112 /* FETCH */
113 SQLCODE = 0;
114 while (SQLCODE <= 100) {
115 EXEC SQL WHENEVER NOT FOUND GO TO OWARI;
116 EXEC SQL 8
117 FETCH CR1 INTO :xscode,:xsname,:xcol,:xtanka,:xgryo; 8
118 EXEC SQL WHENEVER NOT FOUND CONTINUE;
119 printf(" %4s %-16s %2s %8d %8d\n",
120 xscode, xsname, xcol, xtanka, xgryo);
121 }
122
123 OWARI:
124 /* finish */
125 EXEC SQL CLOSE CR1; (a) 9
126 EXEC SQL COMMIT; (b) 9
127 printf(" *** normal ended ***\n");
128
129 FIN:
130 if (input != NULL) {
131 fclose(input);
132 }
133 EXEC SQL WHENEVER SQLERROR CONTINUE;
134 EXEC SQL WHENEVER NOT FOUND CONTINUE;
135 EXEC SQL WHENEVER SQLWARNING CONTINUE;
136 EXEC SQL DISCONNECT; 10
137 return(0);
138 }
139
140
141 void connecterror()
142 {
143
144 printf("\n************ error *** cannot connect ***\n");
145 fclose(input);
146 EXEC SQL DISCONNECT;
147 exit(1);
148 }
149
150
151 void abnormalend()
152 {
153 int wsqlcode;
154
155 wsqlcode = -SQLCODE;
156 printf("\n*** HiRDB SQL ERROR SQLCODE = %d \n", wsqlcode);
157 printf("SQLERRMC = %s\n", SQLERRMC);
158
159 EXEC SQL ROLLBACK; (a) 11
160 EXEC SQL DISCONNECT; (b) 11
161 exit(2);
162 }
<説明>
-
埋込みSQL宣言節の始まりと終わり
UAP中で使用する変数をBEGIN DECLARE SECTIONとEND DECLARE SECTIONとで囲んで,埋込みSQL宣言節の始まりと終わりを示します。
-
HiRDBとの接続
- (a) 特異状態発生時の指定
-
以下のSQLの実行後に,エラー(SQLERROR)が発生した場合の処理として,分岐先(connecterror)を指定します。
- (b) 接続
-
HiRDBに認可識別子及びパスワードを連絡して,UAPがHiRDBを使用できる状態にします。
-
在庫表への行の挿入
在庫表の各列に,埋込み変数に読み込まれた値を挿入します。
-
在庫表の行の更新
- (a) 入庫
-
在庫表から,埋込み変数(:xgno)に読み込んだ品番をキーとして,更新する行を検索します。検索した行の数量(SURYO)の値に,埋込み変数(:xsuryo)に読み込んだ値を加算して,行を更新します。
- (b) 在庫
-
在庫表から,埋込み変数(:xgno)に読み込んだ品番をキーとして,更新する行を検索します。検索した行の数量(SURYO)の値に,埋込み変数(:xsuryo)に読み込んだ値を減算して,行を更新します。
-
在庫表の行の削除
在庫表から,埋込み変数(:xgno)に読み込んだ品番をキーとして,それと等しいキーを持つ行を削除します。
-
カーソルCR1の宣言
在庫表(ZAIKO)の行を検索するために,カーソルCR1を宣言します。
-
カーソルCR1のオープン
在庫表(ZAIKO)の検索行の直前にカーソルを位置づけて,行を取り出せる状態にします。
-
在庫表の行の取り出し
在庫表(ZAIKO)から,カーソルCR1の示す行を1行取り出し,各埋込み変数に設定します。
-
カーソルCR1のクローズとトランザクションの終了
- (a) カーソルCR1のクローズ
-
カーソルCR1を閉じます。
- (b) トランザクションの終了
-
現在のトランザクションを正常終了させて,そのトランザクションによるデータベースへの追加,更新,削除の結果を有効にします。
-
HiRDBの切り離し
UAPをHiRDBから切り離します。
-
トランザクションの取り消し
- (a) トランザクションの無効化
-
現在のトランザクションを取り消して,そのトランザクションによるデータベースへの追加,更新,削除の結果を無効にします。
- (b) HiRDBの切り離し
-
UAPをHiRDBから切り離します。
(2) ユーザ定義のSQL記述領域を使用した例
(a) PADチャート
プログラム例題2のPADチャートを次の図に示します。
|
|
|
|
|
|
|
|
(b) コーディング例
プログラム例題2のコーディング例を次に示します。
1 /******************************************************/
2 /* */
3 /* ALL RIGHTS RESERVED,COPYRIGHT (C)1997,HITACHI,LTD. */
4 /* LICENSED MATERIAL OF HITACHI,LTD. */
5 /* */
6 /* SQLDAを使用したFETCHのサンプル */
7 /* */
8 /******************************************************/
9
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include "pdbsqlda.h" 1
15
16
17 static void Describe();
18 static void Fetch();
19 static void ClearSqlda(short);
20 static void errmsg();
21
22 /***********************************************************/
23 /* GLOBAL VARIABLE */
24 /***********************************************************/
25 short ErrFlg;
26
27 /***********************************************************/
28 /* GLOBAL VARIABLE */
29 /***********************************************************/
30
31 /* sqlda */
32 PDUSRSQLDA(10) xsqlda; 2
33
34 /* sqlcnda */ 3
35 struct { 3
36 short sqlnz; 3
37 struct { 3
38 short sqlnamel; 3
39 char sqlnamec[30]; 3
40 } SQLNAME[10]; 3
41 } ucnda; 3
42
43
44 /***********************************************************/
45 /* */
46 /* MAIN ROUTINE */
47 /* */
48 /***********************************************************/
49 int main(
50 int argc,
51 char *argv[])
52 {
53
54 /***********************************************************/
55 /* CONNECT */
56 /***********************************************************/
57 EXEC SQL
58 WHENEVER SQLERROR GOTO :ERR_EXIT;
59
60 printf("***** connect start \n");
61 EXEC SQL
62 CONNECT; 4
63 printf("***** connect : END\n");
64
65 /***********************************************************/
66 /* DESCRIBE */
67 /***********************************************************/
68 Describe(); 5
69 if(ErrFlg < 0){ 5
70 goto ERR_EXIT; 5
71 } 5
72 5
73 /***********************************************************/ 5
74 /* FETCH */ 5
75 /***********************************************************/ 5
76 Fetch(); 5
77 if(ErrFlg < 0){ 5
78 goto ERR_EXIT; 5
79 } 5
80
81 /***********************************************************/
82 /* END OF ALL */
83 /***********************************************************/
84 ERR_EXIT:
85 if(SQLCODE < 0){
86 errmsg();
87 ErrFlg = -1;
88 }
89
90 EXEC SQL
91 WHENEVER SQLERROR CONTINUE;
92 EXEC SQL
93 WHENEVER NOT FOUND CONTINUE;
94 EXEC SQL
95 WHENEVER SQLWARNING CONTINUE;
96
97 EXEC SQL
98 DISCONNECT; 6
99
100 return(ErrFlg);
101 }
102
103
104 /***********************************************************/
105 /* */
106 /* DYNAMIC CURSOR */
107 /* */
108 /***********************************************************/
109 static void Fetch()
110 {
111 EXEC SQL BEGIN DECLARE SECTION;
112 char XCUSTOM_CD[6];
113 char XCUSTOM_NAME[31];
114 char XTELNO[13];
115 char XZIPCD[4];
116 char XADDRESS[31];
117 EXEC SQL END DECLARE SECTION;
118
119 EXEC SQL
120 WHENEVER SQLERROR GOTO :Exit_Fetch;
121
122 EXEC SQL
123 DECLARE CUR2 CURSOR FOR SEL1; 7
124
125 /***********************************************************/
126 /* OPEN CURSOR */
127 /***********************************************************/
128 printf("***** DYNAMIC CURSOR open start\n");
129 EXEC SQL
130 OPEN CUR2; 8
131 printf("***** DYNAMIC CURSOR open : END\n");
132
133
134 /***********************************************************/
135 /* FETCH */
136 /***********************************************************/
137 printf("***** fetch (use sqlda) start\n");
138
139
140 EXEC SQL
141 WHENEVER NOT FOUND GOTO FETCH2_END;
142
143 for(;;) {
144 ClearSqlda(5); 9
145 PDSQLDATA(xsqlda, 0) = (void *)XCUSTOM_CD; (a) 9
146 PDSQLCOD(xsqlda, 0) = PDSQL_CHAR; (a) 9
147 PDSQLLEN(xsqlda, 0) = sizeof(XCUSTOM_CD)-1; (a) 9
148 PDSQLDATA(xsqlda, 1) = (void *)XCUSTOM_NAME; (b) 9
149 PDSQLCOD(xsqlda, 1) = PDSQL_CHAR; (b) 9
150 PDSQLLEN(xsqlda, 1) = sizeof(XCUSTOM_NAME)-1; (b) 9
151 PDSQLDATA(xsqlda, 2) = (void *)XTELNO; (c) 9
152 PDSQLCOD(xsqlda, 2) = PDSQL_CHAR; (c) 9
153 PDSQLLEN(xsqlda, 2) = sizeof(XTELNO)-1; (c) 9
154 PDSQLDATA(xsqlda, 3) = (void *)XZIPCD; (d) 9
155 PDSQLCOD(xsqlda, 3) = PDSQL_CHAR; (d) 9
156 PDSQLLEN(xsqlda, 3) = sizeof(XZIPCD)-1; (d) 9
157 PDSQLDATA(xsqlda, 4) = (void *)XADDRESS; (e) 9
158 PDSQLCOD(xsqlda, 4) = PDSQL_CHAR; (e) 9
159 PDSQLLEN(xsqlda, 4) = sizeof(XADDRESS)-1; (e) 9
160
161 memset(XCUSTOM_CD, 0, sizeof(XCUSTOM_CD));
162 memset(XCUSTOM_NAME, 0, sizeof(XCUSTOM_NAME));
163 memset(XTELNO, 0, sizeof(XTELNO));
164 memset(XZIPCD, 0, sizeof(XZIPCD));
165 memset(XADDRESS, 0, sizeof(XADDRESS));
166
167 EXEC SQL FETCH CUR2
168 USING DESCRIPTOR :xsqlda; 10
169
170 printf("%s ", XCUSTOM_CD);
171 printf("%s ", XCUSTOM_NAME);
172 printf("%s ", XTELNO);
173 printf("%s ", XZIPCD);
174 printf("%s\n", XADDRESS);
175 }
176 FETCH2_END:
177 printf("***** fetch : END\n");
178
179 /***********************************************************/
180 /* CLOSE CURSOR */
181 /***********************************************************/
182 printf("***** close start\n");
183 EXEC SQL
184 WHENEVER NOT FOUND CONTINUE;
185 EXEC SQL
186 CLOSE CUR2; 11
187 printf("***** close : END\n");
188
189 /***********************************************************/
190 /* */
191 /***********************************************************/
192 Exit_Fetch:
193 if(SQLCODE < 0){
194 errmsg();
195 ErrFlg = -1;
196 }
197 return;
198 }
199
200
201 /***********************************************************/
202 /* DESCRIBE */
203 /***********************************************************/
204 static void Describe()
205 {
206 short i;
207
208 EXEC SQL
209 WHENEVER SQLERROR GOTO :Exit_Describe;
210
211 /***********************************************************/
212 /* PREPARE */
213 /***********************************************************/
214 printf("***** prepare start\n");
215 EXEC SQL 12
216 PREPARE SEL1 12
217 FROM 'SELECT * FROM CUSTOM' 12
218 WITH SQLNAME OPTION; 12
219 printf("***** prepare : END\n");
220
221 /***********************************************************/
222 /* DESCRIBE */
223 /***********************************************************/
224 PDSQLN(xsqlda) = 10;
225 printf("***** describe start\n");
226 EXEC SQL
227 DESCRIBE SEL1 INTO :xsqlda :ucnda; 13
228 printf("***** describe : END\n");
229
230 printf(" describe result\n");
231 printf(" NUMBER OF DATA = %d\n", PDSQLD(xsqlda));
232 printf(" NUMBER OF COLUMN NAME = %d\n", ucnda.sqlnz);
233 for (i = 0 ; i < ucnda.sqlnz ; i++ ) {
234 printf(" [%d]", i );
235 printf(" DATA TYPE(%d)", PDSQLCOD(xsqlda, i));
236 printf(" DATA LENGTH(%d)", PDSQLLEN(xsqlda, i));
237 printf(" COLUMN NAME(%s)\n", ucnda.SQLNAME[i].sqlnamec);
238 }
239
240 /***********************************************************/
241 /* */
242 /***********************************************************/
243 Exit_Describe:
244 if(SQLCODE < 0){
245 errmsg();
246 ErrFlg = -1;
247 }
248 return;
249 }
250
251
252 /***********************************************************/
253 /* Clear SQLDA */
254 /***********************************************************/
255 static void ClearSqlda(
256 short num)
257 {
258 PDSQLN(xsqlda) = num; 14
259 PDSQLD(xsqlda) = num; 14
260 while(num-->0){
261 PDSQLDATA(xsqlda, num) = NULL; 15
262 PDSQLIND(xsqlda, num) = NULL; 15
263 PDSQLDIM(xsqlda, num) = 0; 15
264 PDSQLXDIM(xsqlda, num) = 1; 15
265 PDSQLSYS(xsqlda, num) = 0; 15
266 PDSQLCOD(xsqlda, num) = 0; 15
267 PDSQLLEN(xsqlda, num) = 0; 15
268 }
269 return;
270 }
271
272
273 /**********************************************************/
274 /* */
275 /* WARNING */
276 /* */
277 /***********************************************************/
278 static void errmsg()
279 {
280 int wsqlcode;
281
282 if(SQLCODE > 0){
283 printf(">>>警告\n");
284 }
285 if(SQLCODE < 0){
286 printf(">>> 異常発生\n");
287 }
288 wsqlcode = SQLCODE;
289 printf(">>> sqlcode = %d\n", SQLCODE);
290 printf(">>> sqlwarn = %c", SQLWARN0);
291 printf("%c", SQLWARN1);
292 printf("%c", SQLWARN2);
293 printf("%c", SQLWARN3);
294 printf("%c", SQLWARN4);
295 printf("%c", SQLWARN5);
296 printf("%c", SQLWARN6);
297 printf("%c", SQLWARN7);
298 printf("%c", SQLWARN8);
299 printf("%c", SQLWARN9);
300 printf("%c", SQLWARNA);
301 printf("%c", SQLWARNB);
302 printf("%c\n", SQLWARNC);
303
304 #if defined(HIUXWE2) || defined(WIN32)
305 printf(">>> message = %s\n", SQLERRMC);
306 #else
307 printf(">>> message = %Fs\n", SQLERRMC);
308 #endif
309 return;
310 }
<説明>
-
提供ヘッダファイルのインクルード
SQL記述領域に設定・参照するとき用いるデータコードの定数宣言や,SQL記述領域自体のデータ型を宣言します。
-
SQL記述領域の宣言
UAPでユーザが独自に使用するSQL記述領域を定義します。データ型は提供ヘッダファイルの中で定義されているものです。
-
列名記述領域の宣言
列名をDESCRIBE文で取得するときに用いる,変数を定義します。
-
HiRDBへの接続
環境変数PDUSERに定義されている認可識別子とパスワードを使用してサーバに接続します。
-
顧客表(CUSTOM)の検索
顧客表(CUSTOM)の各列の列名を取得し,表に格納されているすべての行をユーザ定義のSQL記述領域を用いて検索して表示します。
-
HiRDBの切り離し
UAPをサーバから切り離します。
-
カーソルCUR2の宣言
顧客表(CUSTOM)の行を検索するために,カーソルCUR2を宣言します。
-
カーソルCUR2のオープン
顧客表(CUSTOM)の検索行の直前にカーソルを位置づけて,行を取り出せる状態にします。
-
ユーザ定義のSQL記述領域の設定
FETCH文実行時に指定する,ユーザ定義のSQL記述領域の設定をします。
(a) 1列目のデータを格納する領域のアドレスとデータコード,データ長を設定します。
(b) 2列目のデータを格納する領域のアドレスとデータコード,データ長を設定します。
(c) 3列目のデータを格納する領域のアドレスとデータコード,データ長を設定します。
(d) 4列目のデータを格納する領域のアドレスとデータコード,データ長を設定します。
(e) 5列目のデータを格納する領域のアドレスとデータコード,データ長を設定します。
-
顧客表の行の取り出し
顧客表(CUSTOM)から,カーソルCUR2の示す行を1行取り出し,ユーザ定義のSQL記述領域が示す領域に設定します。
-
カーソルCUR2のクローズ
カーソルCUR2を閉じます。
-
SQLの動的実行の用意
DESCRIBE文で顧客表(CUSTOM)の各列の列名とデータ型,データ長を取得するために,表を検索するSELECT文を用意します。
-
列名とデータ型の取得
顧客表(CUSTOM)の各列のデータ型,データ長を取り出して,ユーザ定義のSQL記述領域に設定します。また,各列の列名を取り出して,ユーザ列名記述領域に設定します。
-
ユーザ定義のSQL記述領域の列数の設定
ユーザ定義のSQL記述領域に,SQL記述領域の大きさと取得する列の個数を設定します。
-
ユーザ定義のSQL記述領域のクリア
ユーザ定義のSQL記述領域の中の,各列に対応した領域をクリアします。
(3) LOBデータを操作する例
(a) PADチャート
プログラム例題3のPADチャートを次の図に示します。
|
|
|
|
|
|
(b) コーディング例
プログラム例題3のコーディング例を次に示します。
1 /******************************************************/
2 /* */
3 /* ALL RIGHTS RESERVED,COPYRIGHT (C)1997,HITACHI,LTD. */
4 /* LICENSED MATERIAL OF HITACHI,LTD. */
5 /* */
6 /******************************************************/
7
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <stddef.h>
12 #include <ctype.h>
13 #include <string.h>
14
15 static void InitTable();
16 static void TestBlob();
17 static void warning();
18
19
20 /***********************************************************/
21 /* GLOBAL VARIABLE */
22 /***********************************************************/
23 short ErrFlg;
24
25 EXEC SQL BEGIN DECLARE SECTION;
26 short XSINT_IN;
27 short XSINT_OUT;
28 long XINT_IN;
29 long XINT_OUT;
30 SQL TYPE IS BLOB(16K) XBLOB_IN; 1
31 SQL TYPE IS BLOB(16K) XBLOB_OUT; 1
32 EXEC SQL END DECLARE SECTION;
33
34 /*
35 * name = MAIN
36 * func = SAMPLE
37 * io = argc : i :
38 * argv : i :
39 * return = 0,-1
40 * note = This program needs "RDUSER02" rdarea on Server.
41 * date = 98.04.24 by matsushiba
42 */
43 int main(
44 int argc,
45 char *argv[])
46 {
47 ErrFlg = 0;
48
49 /*************************************************************/
50 /* */
51 /*************************************************************/
52 EXEC SQL
53 WHENEVER SQLERROR goto ERREXIT;
54
55 EXEC SQL
56 WHENEVER SQLWARNING PERFORM :warning;
57
58 EXEC SQL CONNECT; 2
59
60
61 /***********************************************************/
62 /* INIT */
63 /***********************************************************/
64 InitTable(); 3
65 if(ErrFlg < 0){ 3
66 goto ERREXIT; 3
67 } 3
68
69 /**************************************************/
70 /* */
71 /**************************************************/
72 TestBlob(); 4
73 if(ErrFlg < 0){ 4
74 goto ERREXIT; 4
75 } 4
76
77 /*************************************************************/
78 /* */
79 /*************************************************************/
80 ERREXIT:
81 if(SQLCODE < 0){
82 printf(":> ERROR HAPPENED!!\n");
83 warning();
84 ErrFlg = -1;
85 }
86
87 EXEC SQL
88 WHENEVER SQLERROR CONTINUE;
89 EXEC SQL
90 WHENEVER NOT FOUND CONTINUE;
91 EXEC SQL
92 WHENEVER SQLWARNING CONTINUE;
93
94 EXEC SQL DISCONNECT; 5
95
96 return(ErrFlg);
97 }
98
99
100 /***********************************************************/
101 /* INIT */
102 /***********************************************************/
103 static void InitTable()
104 {
105
106 /************************************************************/
107 /* */
108 /************************************************************/
109 EXEC SQL
110 WHENEVER SQLERROR CONTINUE;
111
112 EXEC SQL 6
113 DROP TABLE SMPTBL; 6
114 6
115 EXEC SQL 6
116 CREATE SCHEMA; 6
117
118 printf("## CREATE TABLE\n");
119
120 EXEC SQL
121 WHENEVER SQLERROR GOTO INIT_ERROR;
122
123 printf("## CREATE SMPTBL\n");
124 EXEC SQL 7
125 CREATE TABLE SMPTBL(CLM1 BLOB(30K) IN RDUSER02, 7
126 CLM2 SMALLINT, 7
127 CLM3 INTEGER); 7
128
129 return;
130
131 INIT_ERROR:
132 warning();
133 ErrFlg = -1;
134 return;
135 }
136
137
138
139 /**********************************************************/
140 /* TEST BLOB */
141 /**********************************************************/
142 static void TestBlob()
143 {
144 short cnt;
145
146 EXEC SQL
147 WHENEVER SQLERROR goto :ExitTestBlob;
148
149 EXEC SQL
150 WHENEVER SQLWARNING PERFORM :warning;
151
152 /**********************************************************/
153 /* INSERT */
154 /**********************************************************/
155 memset(XBLOB_IN.XBLOB_IN_data,
156 0x55,
157 sizeof(XBLOB_IN.XBLOB_IN_data));
158 XBLOB_IN.XBLOB_IN_length = sizeof(XBLOB_IN.XBLOB_IN_data);
159
160 printf("## INSERT \n");
161 for(cnt=1; cnt<5; cnt++){
162 XSINT_IN = cnt;
163 XINT_IN = 100+cnt;
164 EXEC SQL 8
165 INSERT INTO SMPTBL 8
166 VALUES(:XBLOB_IN, :XSINT_IN, :XINT_IN); 8
167 }
168 EXEC SQL COMMIT;
169
170 /**********************************************************/
171 /* FETCH */
172 /**********************************************************/
173 printf("## FETCH \n");
174
175 EXEC SQL 9
176 DECLARE CUR_BLOB CURSOR FOR 9
177 SELECT * FROM SMPTBL; 9
178
179 EXEC SQL
180 OPEN CUR_BLOB; 10
181
182 EXEC SQL
183 WHENEVER NOT FOUND GOTO FETCH_END;
184
185 for(;;){
186 memset(XBLOB_OUT.XBLOB_OUT_data,
187 0,
188 sizeof(XBLOB_OUT.XBLOB_OUT_data));
189 XBLOB_OUT.XBLOB_OUT_length = 0;
190 EXEC SQL 11
191 FETCH CUR_BLOB INTO :XBLOB_OUT, 11
192 :XSINT_OUT, 11
193 :XINT_OUT; 11
194
195 printf("CLM1 XBLOB_length == %d\n",
196 XBLOB_OUT.XBLOB_OUT_length);
197 printf("CLM2 = %d\n", XSINT_OUT);
198 printf("CLM3 = %ld\n", XINT_OUT);
199 }
200 FETCH_END:
201 EXEC SQL
202 WHENEVER NOT FOUND CONTINUE;
203
204 EXEC SQL
205 CLOSE CUR_BLOB; 12
206
207 /**********************************************************/
208 /* UPDATE */
209 /**********************************************************/
210 memset(XBLOB_IN.XBLOB_IN_data,
211 0x38,
212 sizeof(XBLOB_IN.XBLOB_IN_data));
213 XBLOB_IN.XBLOB_IN_length = sizeof(XBLOB_IN.XBLOB_IN_data);
214
215 printf("## UPDATE\n");
216 EXEC SQL
217 UPDATE SMPTBL SET CLM1=:XBLOB_IN; 13
218
219 EXEC SQL COMMIT;
220
221 /***********************************************************/
222 /* */
223 /***********************************************************/
224 ExitTestBlob:
225 if(SQLCODE < 0){
226 warning();
227 ErrFlg = -1;
228 }
229 return;
230 }
231
232
233 /***********************************************************/
234 /* WARNING */
235 /***********************************************************/
236 static void warning()
237 {
238 if(SQLCODE < 0){
239 printf(">>>ERROR\n");
240 printf(">>> sqlcode = %d\n", SQLCODE);
241 #if defined(HIUXWE2) || defined(WIN32)
242 printf(":> message = %s\n", SQLERRMC);
243 #else
244 printf(":> message = %Fs\n", SQLERRMC);
245 #endif
246 }
247 else{
248 printf(">>>WARNING\n");
249 printf(">>> sqlwarn = %c", SQLWARN0);
250 printf("%c", SQLWARN1);
251 printf("%c", SQLWARN2);
252 printf("%c", SQLWARN3);
253 printf("%c", SQLWARN4);
254 printf("%c", SQLWARN5);
255 printf("%c", SQLWARN6);
256 printf("%c", SQLWARN7);
257 printf("%c", SQLWARN8);
258 printf("%c", SQLWARN9);
259 printf("%c", SQLWARNA);
260 printf("%c", SQLWARNB);
261 printf("%c\n", SQLWARNC);
262 }
263 return;
264 }
<説明>
-
LOB型の埋込み変数の宣言
書き込み用のLOB型の埋込み変数(:XBLOB_IN)と,読み取り用のLOB型の埋込み変数(:XBLOB_OUT)を宣言します。
-
HiRDBへの接続
環境変数PDUSERに定義されている認可識別子とパスワードを使用してサーバに接続します。
-
表の初期化
LOB型の列を持つ表(SMPTBL)を定義します。
-
LOBデータの挿入・検索・更新
空の表(SMPTBL)にLOB型の列を含む行を挿入し,すべての行を検索した後,LOB型の列の内容を新しいLOBデータに更新します。
-
HiRDBの切り離し
UAPをサーバから切り離します。
-
表(SMPTBL)を作成するための準備
LOB型の列を含む表(SMPTBL)を作成するため,同名の表があった場合は削除し,スキーマがないときのためにスキーマを生成します。
-
LOB型の列を含む表(SMPTBL)を作成する
LOB型の列を含む表(SMPTBL)を作成します。LOBデータはLOB専用のRDエリア(RDUSER02)に格納するように定義するので,サーバにユーザLOB用RDエリアを作成しておかなければなりません。ユーザLOB用RDエリアがない場合はエラーとなります。
-
LOBデータの追加
LOB型の列を持つ表(SMPTBL)に,埋込み変数(:XBLOB_IN,:XINT_IN,:XSINT_IN)に設定した値を追加します。
-
カーソルCUR_BLOBの宣言
LOB型の列を含む表(SMPTBL)を検索するために,カーソルCUR_BLOBを宣言します。
-
カーソルCUR_BLOBのオープン
LOB型の列を含む表(SMPTBL)の検索行の直前にカーソルを位置づけて,各行を取り出せる状態にします。
-
LOB型データの取り出し
LOB型の列を含む表(SMPTBL)のカーソルCUR_BLOBの示す行を1行取り出し,埋込み変数(:XBLOB_OUT,:XINT_OUT,:XSINT_OUT)に設定します。
-
カーソルCUR_BLOBのクローズ
カーソルCUR_BLOBを閉じます。
-
LOBデータの更新
表(SMPTBL)のLOB型の列の値を,埋込み変数(:XBLOB_IN)の値で更新します。