動的SQL

PostgreSQL 9.1.1文書
前のページ | 巻戻し | 第 33章ECPG - C言語による埋め込みSQL | 早送り | 次のページ

# 33.5. 動的SQL

多くの場合、アプリケーションが実行しなければならないSQL文は、アプリケーションを作成する段階で決まります。 しかし、中には、SQL文が実行時に構成されることや外部ソースで提供されることがあります。 このような場合、SQL文を直接Cソースコードに埋め込むことはできません。 しかし、文字列変数として提供される任意のSQL文を呼び出すことができる機能が存在します。

## 33.5.1. 結果セットを伴わない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文に使用することができます（e.g., DDL, `INSERT`, `UPDATE`, `DELETE`)。 結果を受け取るSQL文（e.g., `SELECT`）をこの方法で実行することはできません。 次の節で、その実行方法を説明します。

## 33.5.2. 入力パラメータを伴うSQL文の実行

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

## 33.5.3. 結果セットを返却するSQL文の実行

単一行を編訳する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行以上の結果を返すことが想定される場合、以下の例のようにカーソルを使う必要があります。 （カーソルの詳細については 項33.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 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;

前のページ | ホーム | 次のページ
ホスト変数の使用 | 上に戻る | pgtypes ライブラリ