PostgreSQLに対して以下のDB操作・SQL実行を行うECPGの簡単なプログラム例を示します。
- ローカルで稼働中のPostgreSQLに対して、DBユーザtestuserでデータベースtestdbに接続する。
- (もし未作成であれば) テーブルtesttblを作成する。テーブルtesttblは、主キーであるinteger型の1カラムnumだけを持つ。
- プログラムの引数で指定された整数値をテーブルtesttblにINSERTする。
- テーブルtesttblの全レコードについて、numカラムでソートした結果を順番に標準出力に出力する。
- SQL実行がエラーになった場合は、エラーの理由とSQLをエラーメッセージとして標準エラー出力に出力する。
これらを実現するECPGプログラムの簡単な例は下記です。
test.pgc
#include <stdio.h>
#include <stdlib.h>
/*
* SQL実行でエラーが発生したら、エラー処理のための関数として
* elog()を呼び出すようにグローバルに宣言する。
*/
static void elog(void);
EXEC SQL WHENEVER SQLERROR CALL elog();
/*
* 現在実行中または直前に実行済のSQL文字列を保存する
* グローバル変数sqlを宣言する。
*/
EXEC SQL BEGIN DECLARE SECTION;
char *sql;
EXEC SQL END DECLARE SECTION;
/*
* このプログラムのメイン関数。
* テーブルtesttblにINSERTするレコードの整数値を第1引数で指定できる。
*/
int
main(int argc, char *argv[])
{
/*
* ECPGで使うローカル変数を宣言する。
*/
EXEC SQL BEGIN DECLARE SECTION;
const char *target = "testdb@localhost:5432";
const char *user = "testuser";
int num = 0;
int res = 0;
EXEC SQL END DECLARE SECTION;
/*
* 第1引数が指定された場合は、引数の整数値をINSERTする。
*/
if (argc > 1)
num = atoi(argv[1]);
/*
* ローカル内で稼働中のPostgreSQLに対して、DBユーザtestuserで
* データベースtestdbに接続する。
*/
EXEC SQL CONNECT TO :target USER :user;
/*
* もし未作成であれば、テーブルtesttblを作成する。
*/
sql = "CREATE TABLE IF NOT EXISTS testtbl (num integer primary key)";
EXEC SQL EXECUTE IMMEDIATE :sql;
/*
* 動的SQLを使って、テーブルtesttblにレコードを1件INSERTする。
*/
sql = "INSERT INTO testtbl VALUES (?)";
EXEC SQL PREPARE teststmt FROM :sql;
EXEC SQL EXECUTE teststmt USING :num;
/*
* テーブルtesttblの全レコードを表示するために、全レコードを取得する
* SQLに対してカーソルを定義する。
*/
sql = "SELECT num FROM testtbl ORDER BY num";
EXEC SQL PREPARE teststmt FROM :sql;
EXEC SQL DECLARE testcur CURSOR FOR teststmt;
EXEC SQL OPEN testcur;
/*
* カーソルからレコードを1件ずつ取得して標準出力する。
* 全レコードを取得したらwhile()ループから抜けられるように
* 一時的に宣言する。
*/
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
EXEC SQL FETCH testcur INTO :res;
printf("%d\n", res);
}
EXEC SQL WHENEVER NOT FOUND CONTINUE;
EXEC SQL CLOSE testcur;
/*
* トランザクションを完了する。
*/
sql = "COMMIT";
EXEC SQL EXECUTE IMMEDIATE :sql;
/*
* PostgreSQLへの接続をクローズする。
*/
EXEC SQL DISCONNECT;
return 0;
}
/*
* SQL実行でエラーが発生したときに呼び出される、エラー処理のための関数。
*/
static void
elog(void)
{
/*
* sqlcaからエラー理由のメッセージを取得して、標準エラー出力に出す。
* また、現在実行中または直前に実行済のSQLでエラーとなったものも
* 標準エラー出力に出す。
*/
fprintf(stderr, "ERROR: %s\n", sqlca.sqlerrm.sqlerrmc);
fprintf(stderr, "STATEMENT: %s\n", sql);
exit(1);
}
このECPGプログラムは以下のとおりコンパイルします。以下では、PostgreSQLのインストール先を/opt/pgsqlディレクトリとします。
$ ecpg test.pgc
$ gcc -o test test.c -I/opt/pgsql/include -L/opt/pgsql/lib -lecpg
プログラムの実行例は以下のとおりです。
$ ./test 1
1
$ ./test 2
1
2
$ ./test 0
0
1
2
$ ./test 0
ERROR: duplicate key value violates unique constraint "testtbl_pkey" on line 59
STATEMENT: INSERT INTO testtbl VALUES (?)