[pgsql-jp: 33230] Re: PostgrsSQL7.4.2 ecpgのprepare,execute でnull値が渡せない
Katsuhiko Okano
k_okano @ po.ntts.co.jp
2004年 6月 14日 (月) 19:25:55 JST
岡野と申します。
aya wrote:
>実際のアプリケーションではテーブル名が
>動的にかわるためどうしても動的SQLで
>null値をinsertする必要があります。
「動的SQLでnull値をinsertする」
の意味をうまく理解できていなかったらすみません。
方法は2つあると思います。
1)SQL文を2つ用意して、C言語のif文でどちらかを実行する
2)SQL文にCASE式のNULLIF形式を書いて、NULLか、指定した値かのどちらかを使う
#strcpy()で作る動的SQLを毎回書き換えるとか、INSERT文のVALUES句に何も書かない
#とかも考えましたが、綾さんのケースだと使えそうに無いですね(^^;)
1つのSQL文で行う場合、ホスト変数のNULLとデータベースのNULLは違うため、
oracleのNVL関数のような変換が必要だと思います。
なぜPostgreSQL7.3.3で動いて、PostgreSQL7.4.2で動かないのかは分かりません(--;)
2)の方法で以下のコードを使ってNULLを入れることができたので付けておきます。
(綾さんのソースの39行目にある内容でtmptableテーブルを作成してから実行しました)
長くなってすみません。
#include <stdio.h>
#include <sqlca.h>
void error_exit(void);
int main( int argc, char* argv[] ){
/* ホスト変数 */
exec sql begin declare section;
int indata;
char sqlstring[1000];
exec sql end declare section;
/* エラートラップ定義 */
exec sql whenever sqlerror do error_exit();
/* データベースopen */
EXEC SQL connect to tcp:postgresql://mymachine:12345/testdb02;
/* 動的にinsertする準備 */
memset(sqlstring,'\0',sizeof(sqlstring));
strcpy( sqlstring , "insert into tmptable values ( NULLIF(?,?) )");
EXEC SQL prepare ins_cur from :sqlstring;
/* 動的に通常のデータ登録 */
indata=44;
EXEC SQL execute ins_cur using :indata,10;
/* 動的にNULL値のデータ登録 */
indata=10;
EXEC SQL execute ins_cur using :indata,10;
/* commit */
exec sql commit work;
/* データベースclose */
exec sql disconnect;
exit(0);
}
/* エラー処理 */
void error_exit(void){
fprintf(stderr, "PostgreSQL error : %d[%.*s]\n",
sqlca.sqlcode, sqlca.sqlerrm.sqlerrml,sqlca.sqlerrm.sqlerrmc);
exec sql whenever sqlerror continue;
exec sql rollback;
exec sql disconnect;
exit(1);
}
/*
testdb02=> -- psqlで結果を確認する
testdb02=> select CASE WHEN row1 IS NULL THEN 999 ELSE row1 END from tmptable;
row1
------
44
999
(2 rows)
testdb02=>
*/
--
----------------------------------------
Katsuhiko Okano
k_okano @ po.ntts.co.jp
NTT Software Corp. (division "NBRO-PT6")
pgsql-jp メーリングリストの案内