【JPUG主催】PostgreSQLカンファレンス2020【11月13日開催】
他のバージョンの文書 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

33.7. 動的SQL

多くの場合、アプリケーションが実行しなければならない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;

この方法ではデータを取り出す文(例えばSELECT)を実行することはできません。

任意の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';

実行させる文が値を返す場合、INTO句を付けてください。

EXEC SQL BEGIN DECLARE SECTION;
const char *stmt = "SELECT a, b, c FROM test1 WHERE a > ?";
int v1, v2;
VARCHAR v3;
EXEC SQL END DECLARE SECTION;

EXEC SQL PREPARE mystmt FROM :stmt;
 ...
EXEC SQL EXECUTE mystmt INTO v1, v2, v3 USING 37;

EXECUTEコマンドはINTO句、USING句、この両方を持つことも、どちらも持たないこともできます。

プリペアド文が必要なくなった時、割当てを解除しなければなりません。

EXEC SQL DEALLOCATE PREPARE name;