多くの場合、アプリケーションが実行しなければならないSQL文は、アプリケーションを作成する段階で決まります。 しかし、中には、SQL文が実行時に構成されることや外部ソースで提供されることがあります。 このような場合、SQL文を直接Cソースコードに埋め込むことはできません。 しかし、文字列変数として提供される任意のSQL文を呼び出すことができる機能が存在します。
任意のSQL文を実行するもっとも簡単な方法は、EXECUTE IMMEDIATE コマンドを使用することです。
例を示します:
EXEC SQL BEGIN DECLARE SECTION; const char *stmt = "CREATE TABLE test1 (...);"; EXEC SQL END DECLARE SECTION; EXEC SQL EXECUTE IMMEDIATE :stmt;
EXECUTE IMMEDIATEは結果セットを返却しないSQL文(例えば、DDL、INSERT、UPDATE、DELETE)に使用することができます。
結果を受け取るSQL文(例えば、SELECT)をこの方法で実行することはできません。
次の節で、その実行方法を説明します。
任意のSQL文を実行するより強力な方法は、一度プリペアをし、その後でプリペアド文を実行したいところで実行することです。 また、SQL文を汎用化した形でプリペアし、パラメータを置き換えることで特定のSQL文を実行させることも可能です。 SQL文をプリペアする時、後でパラメータとして置き換えたいところには疑問符を記述してください。 以下に例を示します。
EXEC SQL BEGIN DECLARE SECTION; const char *stmt = "INSERT INTO test1 VALUES(?, ?);"; EXEC SQL END DECLARE SECTION; EXEC SQL PREPARE mystmt FROM :stmt; ... EXEC SQL EXECUTE mystmt USING 42, 'foobar';
プリペアド文が必要なくなった時、割当てを解除しなければなりません。
EXEC SQL DEALLOCATE PREPARE name;
単一行を編訳するSQL文を実行するには、EXECUTE を使うことができます。
結果を保存するには、INTO 句を追加します。
EXEC SQL BEGIN DECLARE SECTION; const char *stmt = "SELECT a, b, c FROM test1 WHERE a > ?"; int v1, v2; VARCHAR v3[50]; EXEC SQL END DECLARE SECTION; EXEC SQL PREPARE mystmt FROM :stmt; ... EXEC SQL EXECUTE mystmt INTO :v1, :v2, :v3 USING 37;
EXECUTEコマンドはINTO句、USING句、この両方を持つことも、どちらも持たないこともできます。
クエリが2行以上の結果を返すことが想定される場合、以下の例のようにカーソルを使う必要があります。 (カーソルの詳細については 36.3.2 を参照してください)
EXEC SQL BEGIN DECLARE SECTION;
char dbaname[128];
char datname[128];
char *stmt = "SELECT u.usename as dbaname, d.datname "
" FROM pg_database d, pg_user u "
" WHERE d.datdba = u.usesysid";
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO testdb AS con1 USER testuser;
EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
EXEC SQL PREPARE stmt1 FROM :stmt;
EXEC SQL DECLARE cursor1 CURSOR FOR stmt1;
EXEC SQL OPEN cursor1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
EXEC SQL FETCH cursor1 INTO :dbaname,:datname;
printf("dbaname=%s, datname=%s\n", dbaname, datname);
}
EXEC SQL CLOSE cursor1;
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;