[pgsql-jp: 33190] PostgrsSQL7.4.2 ecpgのprepare,executeでnull値が渡せない
aya
shigeto_aya_za @ mail.toyota.co.jp
2004年 6月 10日 (木) 13:51:38 JST
綾 重人と申します。
PostgreSQL7.3.3で正常に動いていたecpgプログラムを
PostgreSQL7.4.2にしてコンパイルしたところエラーとなります。
具体的にはprepareでinsert文を宣言し、動的にnull値を含む変数を
insertするためのexecute文で、
コンパイルエラー(syntaxエラー)となります。
エラーとなる行は以下です。
61 EXEC SQL execute ins_cur using :indata:ind_indata;
7.3.3では正常に動きます。
実際のアプリケーションではテーブル名が
動的にかわるためどうしても動的SQLで
null値をinsertする必要があります。
対応方法ご存知の方いらっしゃいましたら
ご教授ください。
わかりにくいと思うので、
サンプルソースより重要な部分を抜粋したものをのせます。
38 /* テーブル作成 */
39 EXEC SQL create table tmptable ( row1 integer );
40
48 /* 動的にinsertする準備 */
49 memset(sqlstring,'\0',sizeof(sqlstring));
50 strcpy( sqlstring , "insert into tmptable values (?)");
51 EXEC SQL prepare ins_cur from :sqlstring;
52
53 /* 動的に通常のデータ登録 これはOK */
54 indata=44;
55 EXEC SQL execute ins_cur using :indata;
56
57 /* 動的にNULL値のデータ登録 */
58 ind_indata=-1;
59 indata=0;
60 /* 本当はこのように書きたい が、コンパイルエラー */
61 EXEC SQL execute ins_cur using :indata:ind_indata;
サンプル全ソースをのせます。(長文すみません。)
ここから ------------------------------------
1 #include <stdio.h>
2 /* #include
</usr/local/src/postgresql-7.4.2/src/interfaces/ecpg/include/sqlca.h> */
3
4 #include <sqlca.h>
5
6 void dbclose(void);
7 void dbopen(void);
8 void error_exit(void);
9
10 int main(int argc, char* argv[]){
11
12 /* ホスト変数 */
13 exec sql begin declare section;
14
15 char sqlstring[1000];
16
17 int indata;
18 int ind_indata;
19
20 int *indata_p;
21
22 int host_row1;
23 int ind_row1;
24
25 exec sql end declare section;
26
27 /* データベースopen */
28 dbopen();
29
30 /* トランザクションレベル */
31 exec sql set transaction isolation level read committed;
32
33 exec sql whenever sqlerror continue;
34
35 /* テーブル削除 */
36 EXEC SQL drop table tmptable;
37
38 /* テーブル作成 */
39 EXEC SQL create table tmptable ( row1 integer );
40
41 /* 静的に通常のデータinsert */
42 EXEC SQL insert into tmptable values (33);
43 printf("insert sqlcode %d\n",sqlca.sqlcode);
44 /* 静的にNULL値のデータinsert */
45 EXEC SQL insert into tmptable values (NULL);
46 printf("insert sqlcode %d\n",sqlca.sqlcode);
47
48 /* 動的にinsertする準備 */
49 memset(sqlstring,'\0',sizeof(sqlstring));
50 strcpy( sqlstring , "insert into tmptable values (?)");
51 EXEC SQL prepare ins_cur from :sqlstring;
52
53 /* 動的に通常のデータ登録 */
54 indata=44;
55 EXEC SQL execute ins_cur using :indata;
56
57 /* 動的にNULL値のデータ登録 */
58 ind_indata=-1;
59 indata=0;
60 /* 本当はこのように書きたい が、コンパイルエラー */
61 EXEC SQL execute ins_cur using :indata:ind_indata;
62 EXEC SQL execute ins_cur using :indata:ind_indata;
63 EXEC SQL execute ins_cur using :indata:ind_indata;
64 EXEC SQL execute ins_cur using :indata:ind_indata;
65 EXEC SQL execute ins_cur using :indata:ind_indata;
66 EXEC SQL execute ins_cur using :indata:ind_indata;
67
68 /* これだと0が登録されてしまう */
69 EXEC SQL execute ins_cur using :indata;
70
71 /* これだとSegmentation fault
72 indata_p=NULL;
73 EXEC SQL execute ins_cur using :indata_p; */
74
75 /* これだとコンパイルエラー
76 ERROR: syntax error at or near ":indata_p"
77 indata_p=NULL;
78 EXEC SQL execute ins_cur using :indata:indata_p; */
79
80 EXEC SQL declare aya_cur cursor for select * from tmptable;
81 printf("declare sqlcode %d\n",sqlca.sqlcode);
82
83 EXEC SQL open aya_cur ;
84 printf("open sqlcode %d\n",sqlca.sqlcode);
85
86 while(1){
87 host_row1=0;
88 ind_row1=0;
89 EXEC SQL fetch in aya_cur into :host_row1:ind_row1;
90 printf("fetch sqlcode=%d error_msg=%s\n",sqlca.sqlcode,
91
sqlca.sqlerrm.sqlerrmc);
92 /* printf("fetch sqlcode=%d error_msg=%s\n",
*/
93 /* (*ECPGget_sqlca()).sqlcode,
*/
94 /*
(*ECPGget_sqlca()).sqlerrm.sqlerrmc); */
95
96 if (sqlca.sqlcode == 100 ) {
97 break;
98 }
99
100 if (ind_row1 == -1 ){
101 printf("row1 is null\n");
102 } else {
103 printf("row1 %d\n",host_row1);
104 }
105 }
106
107 exec sql commit work;
108
109 dbclose();
110
111 exit(0);
112
113 }
114
115 /* エラー処理 */
116 void error_exit(void){
117 fprintf(stderr, "PostgreSQL error : %d[%.*s]\n",
118 sqlca.sqlcode, sqlca.sqlerrm.sqlerrml,
sqlca.sqlerrm.sqlerrmc);
119
120 exec sql whenever sqlerror continue;
121 exec sql rollback;
122 exec sql disconnect;
123
124 exit(1);
125 }
126
127 void dbopen(void){
128 /* データベースに接続 */
129 /* 何らかのエラーが発生した場合は関数 error_exit() をコール
する */
130 exec sql whenever sqlerror do error_exit();
131 /* データベース bookmark へユーザ dbuser として接続する */
132 exec sql connect to aya user aya;
133 }
134
135 void dbclose(void){
136 /* データベース切り離し postgres_sqlca*/
137 exec sql disconnect;
138 }
pgsql-jp メーリングリストの案内