# CHAPTER 7: ダイナミック SQL コマンドリファレンス

この章では、C 言語で表現されるEmpress SQLプリコンパイラのための ダイナミック SQL コマンドの構文を紹介します。 各 SQL コマンドステートメントは、 `EXEC SQL`キーワードで始め、 最後にセミコロン(;)を付けなくてはなりません。 1つのステートメントは複数行にわたって記述することができます。

- ALLOCATE DESCRIPTOR
- AUTOMATIC MEMORY
- CLOSE CURSOR
- DEALLOCATE DESCRIPTOR
- DECLARE CURSOR
- DELETE
- DESCRIBE INOUT
- DESCRIBE INPUT
- DESCRIBE OUTPUT
- EXECUTE
- EXECUTE IMMEDIATE
- MEMORY ALLOCATE
- MEMORY REALLOCATE
- FETCH
- FETCH_AGAIN
- FREE
- GET DESCRIPTOR
- INCLUDE SQLDA
- OPEN
- PREPARE
- SET DESCRIPTOR
- TRIGGER ABORT
- UPDATE

## ALLOCATE DESCRIPTOR

指定された名前のディスクリプタを作成します。

構文 |
    EXEC SQL ALLOCATE DESCRIPTOR descriptor_name
         [WITH MAX (occurrences [, max_name_length])];
`descriptor_name` | ディスクリプタのプリコンパイラ識別子(ディスクリプタ名)。
`occurrences` | ディスクリプタアイテム領域の最大数を指定する整数の定数あるいは変数
`max_name_length` | アイテム名の最大長を指定する整数の定数あるいは変数
SQLCODE |
`0` | 正常です。
`-86` | アロケートしたディスクリプタを管理するテーブルのオーバーフロー。
`-87` | ディスクリプタを再アロケートしようとしました。
注意 | ディスクプタは最初にアロケートされるまで使用することができません。 `occurrences`のデフォルト値は 10 です。 `max_name_length`のデフォルト値は 32 です。
例 1 | 15 のアイテム領域とアイテム名の最大長 40 文字のディスクリプタを作成する コマンドは以下になります。
    EXEC SQL ALLOCATE DESCRIPTOR out_desc WITH MAX (15, 40);
例 2 | アイテム領域として integer 変数`:occ_num`の値によって指定されたアイテム領域と アイテム名の最大長をinteger 変数 `:max_num`を指定して ディスクリプタを作成するコマンドは以下になります。
    EXEC SQL ALLOCATE DESCRIPTOR out_desc WITH MAX (:occ_num, :max_num);

## AUTOMATIC MEMORY

メモリアロケートのオプション指定

構文 |
    EXEC SQL AUTOMATIC MEMORY |ON [NOCHECK]|;
                              |     OFF    |
SQLCODE |
`0` | 正常です。
注意 | アトリビュート値をフェッチするためにポインタ変数を使用する場合、 ユーザーは、アトリビュート値を格納するために明示的にデータのスペースを アロケートするかあるいはEmpress にスペースをアロケートさせるかの どちらかに設定するオプションがあります。 `OFF`が指定された場合（デフォルト)、 ユーザーがスペースをアロケートする必要があります。 `ON`が指定された場合、 Empress が、ポインタ変数のためのスペースをアロケートします。 この場合、ユーザーはスペースの開放の責任を持ちます。 `NOCHECK`オプションを伴った場合は、 解放されないスペースがあってもユーザーに警告をしません。
例 | 以下は、Empressがポインタ変数のためのスペースを アロケートし、スペースの解放するための警告をしないように要求する コマンドになります。
    EXEC SQL AUTOMATIC MEMORY ON NOCHECK;

## CLOSE CURSOR

指定されたカーソルをクローズします。

構文 |
    EXEC SQL CLOSE cursor_name;
`cursor_name` | カーソルのプリコンパイラ識別子(カーソル名)
SQLCODE |
`0` | 正常です。
`-73` | カーソルのクローズエラー。
注意 | カーソルを再オープンするためには、その前にカーソルをクローズする必要があります。
例 | 以下は、カーソル`c1`をクローズするためのコマンドです。 コンテキストのレコードは、カーソルが再オープンされない限り、 取得することはできません。
       EXEC SQL CLOSE c1;

## DEALLOCATE DESCRIPTOR

指定されたディスクリプタを解放します。

構文 |
    EXEC SQL DEALLOCATE DESCRIPTOR descriptor_name;
`descriptor_name` | ディスクリプタのプリコンパイラ識別子(ディスクリプタ名)
SQLCODE |
`0` | 正常です。
`-88` | 指定されたディスクリプタは、既に解放されたディスクリプタです。
注意 | ディスクリプタによって使用されていたメモリは解放されます。 ディスクリプタは解放された後、再アロケートしない限り、 そのディスクリプタを使用することはできません。
例 | `out_desc`ディスクリプタによって使用されていたスペースを解放し、 ディスクリプタを破棄します。
       EXEC SQL DEALLOCATE DESCRIPTOR out_desc;

## DECLARE CURSOR

クエリにカーソル名を関連付け、カーソルの宣言します。

構文 |
    EXEC SQL DECLARE cursor_name  [ | SENSITIVE  | ] [ SCROLL ] CURSOR FOR
                                    | INSENSITIVE|
                                    | ASENSITIVE |

         |statement              | [FOR UPDATE];
         |STATEMENT_NAME variable|
where:
`cursor_name` | カーソルのプリコンパイラ識別子(カーソル名)
`statement` | `プリペア済みのSELECT`ステートメントのプリコンパイラ識別子か、あるいは リテラル文字列か、パラメータなしの`SELECT`ステートメントを格納した変数の いずれかになります。
`variable` | プリコンパラ識別子

SQLCODE

`0` | 正常です。
`-69` | 宣言されたカーソルを管理するテーブルのオーバーフロー。
`-70` | カーソルを再定義しようとしました。

注意

1. １つのカーソル名は、プログラム中で１回のみ宣言できます。 （同じ名前で複数回宣言することはできません。）

2. `INSENITIVE`カーソルは、 その定義されたコンテキストの 効果的に分離したコピーを作成されたカーソルです。 カーソルのアクセスはオリジナルのコンテキストというより、 コピーに対して行われます。そのため、他のプロセスによる オリジナルコンテキストに対する変更はこのカーソルに行われている ようには見えないかもしれません。

3. `SENSITIVE`カーソルはそのコンテキストに対し、 直接、作用します。コピーを作らないため、 コンテキストに行なわれた他の変更は、このカーソルに対し行われた ように見えるかもしれません。

4. `ASENSITIVE`カーソルは、 そのコンテキストのコピーを作成するか作成しないかは インプリメンテーションに定義されます。 デフォルトでは`ASENSITIVE`カーソルです。

5. `SCROLL`が指定された場合、 `FETCH`の全ての形式は許可されます。 （例えば `NEXT`、 `PRIOR`、 `FIRST`、 `LAST`、`ABSOLUTE`、`RELATIVE`) 指定されない場合は、 `FETCH NEXT`のみ許可されます。

6. ステートメントは、問い合わせ(`SELECT` ステートメント)でなければなりません。

7. ステートメントが識別子である場合、 既に `PREPARE`ステートメントによって定義された ステートメント名でなければなりません。

8. ステートメントが、文字列リテラルか変数である場合、 そのクエリにパラメータを指定することはできません。

9. 検索したレコードを更新する場合、カーソルは `FOR UPDATE`を宣言しなくはなりません。

例 1

テーブル`books`の全てのレコードからアトリビュートを 選択するプリペア済みのステートメント`q1`に対して、 カーソル`c1`を宣言します。

       EXEC SQL PREPARE q1 FROM "SELECT * FROM books";
       EXEC SQL DECLARE c1 CURSOR FOR q1;

例 2

文字列リテラルとして指定されたクエリに対して カーソル`c2`を宣言します。 昨日の日付のレコードからすべてのアトリビュートを選択します。

       EXEC SQL DECLARE c2 CURSOR FOR
          "SELECT * FROM weather WHERE w_date = today - 1 day";

例 3

文字列変数として 指定されたクエリに対して カーソル`c3`を宣言します。 注意としてクエリは動的に作成することができますが、 パラメータの使用は準備されていないステートメントに 許可されません。

       strcpy (str, "SELECT * FROM ");
       strcat (str, "table1");
       EXEC SQL DECLARE c3 CURSOR FOR :str;

## DELETE

動的カーソルのカレントレコードの削除。

構文 |
    EXEC SQL DELETE FROM table WHERE CURRENT OF cursor_name;
`table_name` | 削除するためのテーブル名。
`cursor_name` | カーソルのプリコンパラ識別子。
SQLCODE |
`0` | 正常です。
`1` | レコードはロックされています。
`-78` | readモードでオープンされたカーソルから削除しようとしました。
`-79` | カーソルは、単一テーブルで構成しなくてはなりません。
`-80` | 間違ったテーブル名です。
`-81` | 集計関数を含むカーソルです。
`-82` | 内部エラーが検出されました。
注意 | カーソルは、複数のテーブルの参照はしないようにしてください。 カーソルは、集計関数を含めないようにしてください。
例 | 以下のコマンドは、 `ctests`カーソルのカレントレコードを `acid_tests`テーブルから削除します。
       EXEC SQL DELETE FROM acid_tests WHERE CURRENT OF ctests;

## DESCRIBE INOUT

ディスクリプタのアイテム領域にクエリの選択アイテムを関連付けます。

構文 |
    EXEC SQL DESCRIBE [INOUT] statement_name

        |USING| SQL DESCRIPTOR descriptor_name;
        |INTO |
`statement_name` | プリペア済みのSQLステートメントのプリコンパイラ識別子(ステートメント名)
`descriptor_name` | ディスクリプタのプリコンパイラ識別子(ディスクリプタ名)
SQLCODE |
`0` | 正常です。
`-88` | 解放されたディスクリプタを使用しました。
`-89` | 間違ったステートメント名です。
`-90` | ディスクリプタは要求より、少ない領域しか持っていません。
`-91` | ディスクリプタはカレントカーソルに関連付けられなければなりません。
`-102` | 同じステートメントに基づいた複数オープンされたカーソルです。
注意 | describe する前には必ずディスクリプタは、アロケートしなければなりません。 出力するためのディスクリプタを describe する前に クエリのカーソルはオープンしなければなりません。 クエリ中の選択アイテムの数が、ディスクリプタ中のアイテム領域の最大数を 越えた場合、コマンドは失敗します。 出力するための describe の後に、 クエリ中の選択アイテムの数は、`COUNT`フィールドを読むことで 判断することができます。 指定されたステートメントに基づいた複数オープンされたカーソルがある場合、 Empressは、そのディスクリプタが関連すべきカーソルかどうかわからないため、 コマンドは失敗します。
例 | このステートメントは、ディスクリプタ`inout_desc`中の アイテム領域にクエリ`select1`の選択アイテムを関連付けます。
       EXEC SQL DESCRIBE INOUT select1 INTO SQL DESCRIPTOR inout_desc;

## DESCRIBE INPUT

ディスクリプタのアイテム領域にプリペア済み SQL ステートメント中の パラメーターを関連付けます

構文 |
    EXEC SQL DESCRIBE INPUT statement_name

        |USING| SQL DESCRIPTOR descriptor_name;
        |INTO |
`statement_name` | プリペア済み SQL ステートメントのプリコンパイラ識別子(ステートメント名)
`descriptor_name` | ディスクプタのプリコンパイラ識別子(ディスクリプタ名)
SQLCODE |
`0` | 正常です。
`-88` | 解放されたディスクリプタを使用しました。
`-89` | 誤ったステートメント名です。
`-90` | ディスクリプタは要求より、少ない領域しか持っていません。
`-101` | パラメータなしのステートメントの describe をしようとしました。
注意 | describe する前には必ずディスクリプタは、アロケートしなければなりません。 プリペア済みのパラメータの数が、ディスクリプタ中のアイテム領域の最大数を 越えた場合、コマンドは失敗します。 入力するための describe の後に、 プリペア済みのステートメント中のパラメータの数は、`COUNT`フィールドを読むことで 判断することができます。
例 | このステートメントは、ディスクリプタ`in_desc`中の アイテム領域にプリペア済みのステートメント`update1`の パラメータを関連付けます。
       EXEC SQL DESCRIBE INPUT update1 INTO SQL DESCRIPTOR in_desc;

## DESCRIBE OUTPUT

ディスクリプタのアイテム領域にクエリの選択アイテムを関連付けます。

構文 |
    EXEC SQL DESCRIBE [OUTPUT] statement_name

        |USING| SQL DESCRIPTOR descriptor_name;
        |INTO |
`statement_name` | プリペア済みのSQLステートメントのプリコンパイラ識別子(ステートメント名)
`descriptor_name` | ディスクリプタのプリコンパイラ識別子(ディスクリプタ名)
SQLCODE |
`0` | 正常です。
`-88` | 解放されたディスクリプタを使用しました。
`-89` | 誤ったステートメント名です。
`-90` | ディスクリプタは要求より、少ない領域しか持っていません。
`-91` | ディスクリプタはカレントカーソルに関連付けられなければなりません。
`-102` | 同じステートメントに基づいた複数オープンされたカーソルです。
注意 | describe する前には必ずディスクリプタは、アロケートしなければなりません。 出力するためのディスクリプタを describe する前に クエリのカーソルはオープンしなければなりません。 クエリ中の選択アイテムの数が、ディスクリプタ中のアイテム領域の最大数を 越えた場合、コマンドは失敗します。 出力するための describe の後に、 クエリ中の選択アイテムの数は、`COUNT`フィールドを読むことで 判断することができます。 指定されたステートメントに基づいた複数オープンされたカーソルがある場合、 Empressは、そのディスクリプタが関連すべきカーソルかどうかわからないため、 コマンドは失敗します。
例 | このステートメントは、ディスクリプタ`out_desc`中の アイテム領域にクエリ`select1`の選択アイテムを関連付けます。
       EXEC SQL DESCRIBE OUTPUT select1 INTO SQL DESCRIPTOR out_desc;

## EXECUTE

変数により保持された値またはディスクリプタ領域 によりステートメント中のパラメータを置き換え、 プリペア済みの SQL ステートメントを実行します。

構文 |
    EXEC SQL EXECUTE statement_name

       [USING |variable {, variable}         |];
              |SQL DESCRIPTOR descriptor_name|
`statement_name` | プリペア済み SQL ステートメントのプリコンパイラ識別子 (ステートメント名)
`descriptor_name` | ディスクリプタのプリコンパイラ識別子(ディスクリプタ名)
`variable` | オプションとして制御変数を指定することが可能な変数
SQLCODE |
`0` | 正常です。
`-60` | 定義されていないプリペア済みステートメント名です。
`-61` | 実際のパラメータ数が不正です。
`-64` | `USING`句内のデータタイプが間違っています。
`-65` | SQL プロセッサーは、エラーを検出しました。
`-66` | `SELECT`ステートメントを実行しようとしました。
`-67` | ダイナミックステートメントの実行の間にシグナルをキャッチしました。
`-68` | ダイナミックステートメントの実行の間に未定義のエラーを検出しました。
`-88` | 解放されたディスクリプタを使用しました。
`-96` | 出力ディスクリプタが使用されました。
`-97` | ディスクリプタは、指定されたステートメントのプリペアされていません。
注意 | 問い合わせ(`SELECT` ステートメント)は実行できません。 トランザクションコマンド(`START TRANSACTION`のような)は実行できません。 ステートメント名は、既に`PREPARE`ステートメントに よって定義されなければなりません。 `USING`句は、プリペア済みのステートメントに対し 変数に保持されているか、あるいはディスクリプタ領域に保持された値に 置き換えることが可能です。 `USING`句中の変数の数は、プリペア済みのステートメント内の パラメータの数に一致しなくてはなりません。 ディスクリプタが使用された場合、指定されたステートメントの describe は 入力ディスクリプタにでなくてはなりません。 statementが、call statementか assign statementである場合、実行後、結果としてあれば返されます。
例 1 | 以下の例では、 テーブル`messages`のアトリビュートに名前付きのインデックスを作成する ため、SQL ステートメントを最初に準備します。 インデックスを作成するアトリビュートとインデックスの名前を 指定するために`USING`句を伴いステートメントを実行します。
       EXEC SQL PREPARE index1 FROM "CREATE INDEX ? ON messages (?)";
       EXEC SQL EXECUTE index1 USING :idx_name, :idx_attr;
例 2 | 以下のコマンドは、 プリペア済みのステートメント`ps1`を実行します。 そのステートメントのパラメータに ディスクリプタ`desc1`に含まれるデータ値を置き換えます。
       EXEC SQL EXECUTE ps1 USING SQL DESCRIPTOR desc1;

## EXECUTE IMMEDIATE

パラメータが含まれない SQL ステートメントを実行します。

構文 |
    EXEC SQL EXECUTE IMMEDIATE sql_statement;
`sql_statement` | 実行するためのリテラル文字列か、あるいはSQLステートメントを格納した文字配列変数
SQLCODE |
`0` | 正常です。
`-65` | SQL プロセッサーは、エラーを検出しました。
`-66` | `SELECT`ステートメントを実行しようとしました。
`-67` | ダイナミックステートメントの実行の間、シグナルをキャッチしました。
`-68` | ダイナミックステートメントの実行の間、未定義のエラーを検出しました。
注意 | 問い合わせ(`SELECT` ステートメント)は実行できません。 トランザクションコマンド(`START TRANSACTION`のような)は実行できません。
例 1 | 以下の指定されたアトリビュートを持つテーブルを作成するコマンド例です。
       EXEC SQL EXECUTE IMMEDIATE "CREATE messages
            (sender    CHAR(50,1),
             receiver  CHAR(50,1),
             timestamp TIME(2),
             message   TEXT(20,20,20,1))";
例 2 | 以下は、文字列変数`str_var`に含まれているステートメントを実行するコマンド例です。
       EXEC SQL EXECUTE IMMEDIATE :str_var;

## MEMORY ALLOCATE

ポインタ変数のスペース(メモリ)をアロケートします。

構文 |
    EXEC SQL MEMORY ALLOCATE variable(|size    |);
                                      |variable|
`variable` | ポインタ変数
`size` | ポインタ変数にメモリアロケートするサイズ
SQLCODE |
`0` | 正常です。
`-1` | メモリーアロケートに失敗しました。
注意 | アロケートしたスペースを解放するために `EXEC SQL MEMORY FREE`を使用する必要があります。
例 |
    ...
    char* ptr;
    ...
    EXEC SQL MEMORY ALLOCATE :ptr (20);
    ...
    EXEC SQL FETCH cursor1 into :ptr;
    ...
    EXEC SQL MEMORY FREE :ptr;
    ...

## MEMORY REALLOCATE

ポインタ変数のアロケートしたスペース(メモリ)のサイズを変更します。

構文 |
    EXEC SQL MEMORY REALLOCATE variable(|size    |);
                                        |variable|
`variable` | ポインタ変数
`size` | ポインタ変数に再アロケートするメモリの修正したサイズ
SQLCODE |
`0` | 正常です。
`-1` | メモリの再アロケートに失敗しました。
注意 | 再アロケートしたスペースを解放するために `EXEC SQL MEMORY FREE`を使用する必要があります。
例 |
    ...
    char* ptr;
    ...
    EXEC SQL MEMORY ALLOCATE :ptr (20);
    ...
    EXEC SQL MEMORY REALLOCATE :ptr (40);
    ...
    EXEC SQL FETCH cursor1 into :ptr;
    ...
    EXEC SQL MEMORY FREE :ptr;
    ...

## FETCH

定義したコンテキストの指定されたレコードのカーソルを操作し、 カレントレコードの選択アイテムの値を 変数またはディスクリプタ領域に読み込みます。

構文 1 |
    EXEC SQL FETCH [|NEXT           |[AGAIN][FROM]] cursor_name
                    |PRIOR          |
                    |FIRST          |
                    |LAST           |
                    |ABSOLUTE offset|
                    |RELATIVE offset|
         INTO |variable {, variable }        |;
              |SQL DESCRIPTOR descriptor_name|
構文 2 |
    EXEC SQL FETCH  | emptrig_cursor_old |  [attr {, attr}]
                    | emptrig_cursor_new |
         INTO |variable {, variable }        |;
              |SQL DESCRIPTOR descriptor_name|
`cursor_name` | 定義されたカーソルのプリコンパイラ識別子（カーソル名）
`offset` | レコード数の整数のリテラルか変数で指定します。
`variable` | オプションとして制御変数を指定することが可能な変数
`descriptor_name` | ディスクリプタのプリコンパイラ識別子（ディスクリプタ名）
`emptrig_cursor_old` | トリガーで使用するカーソルのプリコンパイラ予約識別子
`emptrig_cursor_new` | トリガーで使用するカーソルのプリコンパイラ予約識別子
`attr` | アトリビュート名。
SQLCODE |
`0` | 正常です。
`1` | レコードはロックされています。
`100` | これ以上レコードはありません。
`-74` | 変数またはディスクリプタ領域の数が間違っています。
`-76` | 変数のタイプが間違っています。
`-77` | 内部変換エラー。
`-88` | 解放されたディスクリプタが使用されました。
`-97` | ディスクリプタの指定されたステートメントは準備されていません。
`-98` | 入力ディスクリプタが使用されました。
`-99` | 無効なカーソルが使用されました。
SQLWARN1 |
`''` | 切り詰め処理なし。
'`W`' | 切り詰め処理を実行
注意 | フェッチされたレコードがアクセスできない場合（ロックされている場合）、 そのレコードがカレントレコードになりますが、 選択アイテムのレコードは、変数およびディスクリプタ領域に 読む込むことができません。 `FETCH ABSOLUTE`オフセットは "n" レコード分のカーソルを移動します。 ("n"が負の数である場合、終わりから前方に数えます。) `FETCH RELATIVE`オフセットは カレントレコードから "n" レコード分カーソルを移動します。 ("n"が負の数である場合、前方に数えます。) `FETCH FIRST`は 最初のレコードにカーソルを移動します。 `FETCH LAST`は、 最後のレコードにカーソルを移動します。 INTO句中の変数の数は、選択したアイテム数と等しくなくてはなりません。 変数が使用された場合、選択アイテムのデータタイプからホストの変数の データタイプへデータ変換が自動的に実行されます。 これは、外部(文字列)フォーマットの検索するため数値を許可します。 ディスクリプタが使用された場合、このカーソルを定義するために 使用されたステートメントに対して describe した出力ディスクリプタ でなくてはなりません。 制御変数 (またはディスクリプタ領域のDA_CNTRLフィールド)に 負の値がセットされた場合、 フェッチされたアイテムはNULLになります。 配列変数へのフェッチの場合、 読み込んだデータより、配列のサイズが小さい場合は、 切り詰め処理が行われる可能性があります。 このような場合、 `SQLWARN1`に'`W`'が設定され、 制御変数は実際のデータ長を示す数が設定されます。 その長さは C の short 型で表されます。 予約カーソル識別子 `emptrig_cursor_old`、 `emptrig_cursor_new`が指定された場合、 `DECLARE CURSOR`、 `OPEN CURSOR`、 `CLOSE CURSOR`コマンドは使用することはできません。 さらに、`FETCH`オプション、 `NEXT`、`PRIOR`、 `ABSOLUTE`、`RELATIVE`もまた 使用できません。
例 1 | カーソル`c1`によって検索されたコンテキストの次のレコードが カレントになり、 変数`v1`と`v2`へ選択アイテムの値はコピーされます。 `v1` and `v2`.
       EXEC SQL FETCH c1 INTO :v1, :v2;
Example 2 | カーソル`c2`の次のカーソルがカレントになり、 ディスクリプタ`d2`へ選択アイテムの値はコピーされます。
       EXEC SQL FETCH c2 INTO SQL DESCRIPTOR d2;

## FETCH_AGAIN

カレントレコードを読み込み、 選択アイテムの値を取得します。 その値を変数またはディスクリプタ領域に格納します。

構文 |
    EXEC SQL FETCH_AGAIN cursor_name

       [INTO |variable {, variable }        |];
             |SQL DESCRIPTOR descriptor_name|
`cursor_name` | 定義されたカーソルのプリコンパイラ識別子（カーソル名）
`descriptor_name` | ディスクリプタのプリコンパイラ識別子（ディスクリプタ名）
`variable` | オプションとして制御変数を指定することが可能な変数
SQLCODE |
`0` | 正常です。
`1` | レコードはロックされています。
`100` | これ以上レコードはありません。
`-74` | 変数またはディスクリプタ領域の数が間違っています。
`-76` | 変数のタイプが間違っています。
`-77` | 内部変換エラー。
`-88` | 解放されたディスクリプタが使用されました。
`-97` | ディスクリプタの指定されたステートメントは準備されていません。
`-98` | 入力ディスクリプタが使用されました。
`-99` | 無効なカーソルが使用されました。
SQLWARN1 |
`''` | 切り詰め処理なし。
'`W`' | 切り詰め処理を実行
注意 | 通常、`FETCH`コマンドを使用した後に ロックされたレコードが見つかった場合にそのレコードの 再読み込みを試みます。 `INTO`句中の変数の数は、 実際の選択したアイテム数と等しくなくてはなりません。 変数が使用された場合、 選択アイテムのデータタイプから ホストの変数のデータタイプへ データ変換が自動的に実行されます。 これは、外部(文字列)フォーマットの検索するため 数値を許可します。 ディスクリプタが使用された場合、 このカーソルを定義するために使用されたステートメントに 対して describe した出力ディスクリプタでなくてはなりません。 制御変数 (またはディスクリプタ領域の`DA_CNTRL`フィールド)に 負の値がセットされた場合、フェッチされたアイテムは`NULL`になります。 配列変数へのフェッチの場合、 読み込んだデータより、配列のサイズが小さい場合は、 切り詰め処理が行われる可能性があります。 このような場合、 `SQLWARN1`に'`W`'が設定され、 制御変数は実際のデータ長を示す数が設定されます。 その長さは C の short 型で表されます。
例 1 | カーソル`c1`により検索されたコンテキストのカレントレコードを 再読み込みし、選択アイテムの値を変数`v1`と`v2`へ コピーします。
       EXEC SQL FETCH_AGAIN c1 INTO :v1, :v2;
例 2 | カーソル`c2`のカレントレコードを再読み込みし、 選択アイテムの値を`d2`ディスクリプタ内へ コピーします。
       EXEC SQL FETCH_AGAIN c2 INTO SQL DESCRIPTOR d2;

## FREE

自動的にポインタ変数にアロケートされたスペースを解放します。 `AUTOMATIC MEMORY` オプションが`ON`である場合、 Empress は、データの取得時にポインタ変数にスペースをアロケートします。 スペースの解放はプログラマの責任となります。

構文 |
    EXEC SQL MEMORY FREE variable {,variable};
`variable` | 変数
SQLCODE |
`0` | OK.
注意 | このステートメントは、前のバージョンの`mpdfree`の置き換えになります。 `EXEC SQL MEMORY FREE`にアロケートしていない変数を 渡してはいけません。
例 |
    ...
    char* ptr;
    ...
    EXEC SQL AUTOMATIC MEMORY ON;
    ...
    EXEC SQL FETCH cursor1 into :ptr;
    ...
    EXEC SQL FREE :ptr;
    ...

## GET DESCRIPTOR

ディスクリプタのフィールド値を読み込みます。

構文 |
    EXEC SQL GET DESCRIPTOR descriptor_name
|  |  | `|var = COUNT |VALUE item var = field_name {, var = field_name}` | `|; |`
`descriptor_name` | ディスクリプタのプリコンパイラ識別子(ディスクリプタ名)
`item` | アクセスするためのアイテム領域指定の整数定数および変数
`field_name` | 以下の識別子の内の１つ
|  |  | `DA_TYPE` | コードのデータタイプ
|  |  | `DA_NAME` | アイテム名
|  |  | `DA_NLEN` | 名前の長さ
|  |  | `DA_DATA` | データ値
|  |  | `DA_CNTRL` | 制御変数に等しい
`var` | 埋め込み変数
SQLCODE |
`0` | 正常です。
`-76` | 間違ったタイプの変数です。
`-77` | 内部変換エラー
`-88` | 解放されたディスクリプタが使用されました。
`-92` | 間違ったディスクリプタ領域の指定です。
`-94` | 無効なディスクリプタです。
`-95` | 間違った変数のデータタイプです。
4. 注意 | 入力のために describe したディスクリプタは データはフィールドに割り当てられていない場合のみに `COUNT`フィールドに有効な情報が格納されます。 出力のために describe し、フェッチに使用されたディスクリプタの場合、 すべてのフィールドにおいて有効な情報が格納されます。 `COUNT`フィールドは ディスクリプタの有効なアイテムエリアの数を示す整数値を格納します。 `DA_TYPE`フィールドは、 アトリビュートのデータタイプあるいは選択アイテムを表す整数値を格納します。 以下はデータタイプを識別するために使用される定義です。
   |  |  | `DTGCHAR` | Generic character data type
   |  |  | `DTGINTEGER` | Generic integer data type
   |  |  | `DTGFLOAT` | Generic float data type
   |  |  | `DTGTEXT` | Empress `TEXT` data type
   |  |  | `DTGBULK` | Empress `BULK` data type
   |  |  | `DTGDATE` | Empress `DATE` data type
   |  |  | `DTGTIME` | Empress `TIME` data type
   |  |  | `DTGDECIMAL` | `DECIMAL` and `DOLLAR` data type
`DA_NAME`は、 選択アイテムの特別な名前の文字列を格納します。 選択アイテムがアトリビュートの場合、 `DA_NAME`は、アトリビュート名を保持します。 選択アイテムが式での場合は `DA_NAME`は、"`EXPRESSION_n`"( n のところは整数値)の文字列を 格納します。 選択アイテムが`PRINT`句の場合は `DA_NAME`は、指定されたヘッダーを含みます。 `DA_NLEN`フィールドは、 選択アイテムの名前の文字数を示す整数値を格納します。 `DA_DATA`フィールドは、 `FETCH`ステートメントによって取得した実際のデータを 保持します。 このフィールドの内容を得るために使用される変数は、 `DA_TYPE`に対し適切なデータタイプでなければなりません。 Empressは可能であれば、データタイプ変換の実行を試みます。 （例えば、C 浮動小数点型(float) を使って`DTGDECIMAL`データを 取得する場合） `DA_CNTRL`フィールドは、制御変数として使用されます。 この値が負である場合、取得されたデータは`NULL`になります。 このフィールドにアクセスするために使用する変数は、C の short 型でなければなりません。
例 1 | Integer変数`num`は、 ディスクリプタ`d1`の有効なアイテム領域の数を integerの変数`num`に割り当てます。 `d1`は、２つのパラメータを含むステートメント`in1`に 関連付けられているため、 `num`に、整数値の 2 が割り付けられます。
       EXEC SQL PREPARE in1 FROM "INSERT INTO t1 (a, b) VALUES (?, ?)";
       EXEC SQL DESCRIBE INPUT in1 INTO SQL DESCRIPTOR d1;
       EXEC SQL GET DESCRIPTOR d1 :num = COUNT;
例 2 | 以下の例は、 ディスクリプタは 検索するためのアトリビュートが不明な クエリを describe するために使用されます。 `COUNT`フィールドは、検索アイテムの数を検出する ために使用されます。 ディスクリプタへのフェッチの後、 最初のアトリビュートの名前は、変数`aname`に アサインされ、 このアトリビュートの値は、 変数`aval`にアサインされます。 データタイプコードは、変数`atype`にアサインされ、 変数`anul`は、`NULL`値のチェックのために使用されます。
       EXEC SQL PREPARE sel1 FROM "SELECT * FROM tab1";
       EXEC SQL DESCRIBE OUTPUT sel1 INTO SQL DESCRIPTOR d2;
       EXEC SQL GET DESCRIPTOR d2 :num = COUNT;
       EXEC SQL DECLARE c1 CURSOR FOR sel1;
       EXEC SQL OPEN c1;
       EXEC SQL FETCH c1 INTO SQL DESCRIPTOR d2;
       EXEC SQL GET DESCRIPTOR d2 VALUE 1 :aname=DA_NAME, :aval=DA_DATA,
                :atype=DA_TYPE, :anul=DA_CNTRL;

## INCLUDE SQLDA

SQL ディスクリプタの定義のインクルード。 このステートメントは、SQLディスクリプタを使用する前に必ず プログラムのグローバルセクションに記述しなければなりません。

構文 |
    EXEC SQL INCLUDE SQLDA;
SQLCODE | 意味はありません。
注意 | このステートメントは、ディスクリプタを使用しない場合は必要ありません。 通常、`INCLUDE SQLCA`ステートメントの後に記述します。

## OPEN

`SELECT`ステートメント中のパラメータを 変数またはディスクリプタ領域に保持された値に置き換え、 検索された複数のレコードのための指定されたカーソルをオープンします。

構文 |
    EXEC SQL OPEN cursor_name

       [USING |variable {, variable}         |];
              |SQL DESCRIPTOR descriptor_name|
where:
`cursor_name,` | 定義したカーソルのプリコンパイラ識別子(カーソル名)
`descriptor_name` | ディスクリプタのプリコンパイラ識別子(ディスクプタ名)
`variable` | オプションとして制御変数を指定することが可能な変数
SQLCODE |
`0` | 正常です。
`-60` | 未定義のプリペア済みステートメント名です。
`-61` | 実際のパラメータ数が不正です。
`-64` | `USING`句の間違ったデータタイプです。
`-71` | 既にオープンされたカーソルをオープンしようとしました。
`-72` | オープンカーソルエラー。
`-88` | 解放されたディスクリプタを使用しました。
`-90` | ディスクリプタは要求より、少ない領域しか持っていません。
`-96` | 出力ディスクリプタが使用されました。
`-97` | ディスクリプタは、指定されたステートメントを準備していません。
`-100` | `SELECT`ステートメントではないカーソルのオープンをしようとしました。
注意 | カーソル名は既に定義されなければなりません。 `USING`句は、プリペア済みのステートメントのパラメータに対し、 変数に保持されているか、あるいはディスクリプタ領域に保持された値に 置き換えることが可能です。 USING句中の変数の数は、プリペア済みのステートメント内の パラメータの数に一致しなくてはなりません。 ディスクリプタが使用された場合、指定されたステートメントの describe は 入力ディスクリプタにでなくてはなりません。
例 1 | カーソル`c1`をオープンします。 `USING`句が指定されていないため、カーソルへのクエリの関連は パラメータとして持つことはできません。
       EXEC SQL OPEN c1;
例 2 | カーソル`c2`をオープンします。 クエリステートメント中の３つ変数の置き換えのため、 正確に３つのパラメータを与える必要があります。
       EXEC SQL OPEN c2 USING :v1, :v2, :v3;
例 3 | カーソル`c3`をオープンします。 クエリステートメント中に値の置き換えのために 任意の数のパラメータを持つことができる SQL ディスクリプタを使用します。
       EXEC SQL OPEN c3 USING SQL DESCRIPTOR d3;

## PREPARE

後に利用するための SQL ステートメントを準備します。 疑問符(?)によって表されたパラメータを含むSQLステートメントと ステートメント名を関連付けます。

構文 |
`EXEC SQL PREPARE statement_name FROM` | `|sql_statement |call_statement` | `|; |`
`statement_name` | このステートメントを後で参照するために使用するプリコンパイラ識別子(ステートメント名)
`sql_statement` | リテラル文字列か、実行するためのSQLステートメントを含む文字配列変数
`call_statement` |
`CALL` | `|expr |procedure_name [([expr {, expr}])]` | `|; |`
SQLCODE |
`0` | 正常です。
`-62` | 無効な`PREPARE`ステートメントです。
`-63` | プリペア済みステートメントのテーブルがオーバーフローしました。
注意 | パラメータに含まれるSQL ステートメントは､使用する前に必ず準備されなければ なりません。 ステートメント名は、既に定義されていた可能性があります。 この場合、前の定義は失われ、ステートメント名は新しいSQL ステートメントと 関連付けられます。
例 1 | 以下は、後に実行するための`DROP`ステートメントを準備するコマンドです。 パラメータは実行時に指定されたレコードを削除するために使用することが可能です。
        EXEC SQL PREPARE drop_t1 FROM
          "DROP FROM books WHERE title MATCH ?";
例 2 | 以下のステートメントは、準備前に動的にSQLステートメントを 作成の方法を示します。
       strcpy (sqls, "SELECT ");
       strcat (sqls, "title, publisher, price ");
       strcat (sqls, "FROM books");
       EXEC SQL PREPARE query1 FROM :sqls;
例 3 | このコマンドは、後で実行するプロシージャ`proc`の `CALL`ステートメントの準備をします。
       SQL EXEC PREPARE call_s1 FROM "CALL proc (?, ?, ?)";

## SET DESCRIPTOR

プリペア済みのステートメント中のパラメータに値を割り付ける目的で、 ディスクリプタのフィールドに値を設定します。

構文 |
    EXEC SQL SET DESCRIPTOR descriptor_name
         VALUE item field_name = val  {, field_name = val};
where:
`descriptor_name` | ディスクリプタのプリコンパイラ識別子(ディスクリプタ名)
`item` | 整数の定数か、またはアクセスするためのアイテム領域を指定する変数
`field_name` | 以下の識別子の内の１つ
|  |  | `DA_DATA` | データ値
|  |  | `DA_CNTRL` | 制御変数と同等
`val` | リテラル値か変数
SQLCODE |
`0` | 正常です。
`-88` | 解放されたディスクリプタを使用しました。
`-92` | 間違ったディスクプタ領域が指定されています。
`-93` | 出力ディスクリプタへの更新をしようとしました。
注意 | ディスクリプタは、入力するために describe されなくてはなりません。 出力のために describeされた場合、そのフィールドへの値のアサインはできません。 `DA_DATA`フィールドには、プリペア済みのステートメント中のパラメータ を置き換える実際の値を割り付けなければなりません。 Empressは、必要であればデータタイプ変換の実行を試みます。 （例えば、`DOLLAR`アトリビュートに C の doubule の変数 を割り付ける場合や、 `DATE`アトリビュートに 文字列をアサインする場合など) `DA_CNTRL`フィールドは、制御変数として使用されます。 マイナスの値を割り付ける場合、データは`NULL`です。 このフィールドを使用する変数は C の short 型でなければなりません。
例 | 以下のSQLステートメントと同等のステートメントの例です `INSERT INTO tab1 (name, code) VALUES ('John', null)`
       EXEC SQL PREPARE in1 FROM "INSERT INTO tab1 (?, ?) VALUES (?, ?)";
       EXEC SQL DESCRIBE INPUT in1 INTO SQL DESCRIPTOR d1;
       EXEC SQL SET DESCRIPTOR d1 VALUE 1 DA_DATA="name";
       EXEC SQL SET DESCRIPTOR d1 VALUE 2 DA_DATA="code";
       i = 3;
       strcpy (str, "ÕJohnÕ");
       EXEC SQL SET DESCRIPTOR d1 VALUE :i DA_DATA=:str;
       EXEC SQL SET DESCRIPTOR d1 VALUE 4 DA_CNTRL=-1;
       EXEC SQL EXECUTE in1 USING SQL DESCRIPTOR d1;

## TRIGGER ABORT

トリガー PSM プロシージャを中断します。

構文 | `EXEC SQL TRIGGER ABORT;`
SQLCODE | 意味はありません。
注意 | トリガー PSM プロシージャだけで使用することができます。

## UPDATE

ダイナミックカーソルのカレントレコードの更新をします。

構文 |
    EXEC SQL UPDATE |table_name| SET |attr = variable {, attr = variable}|
                    |CURRENT   |     |attr {, attr} VALUES attr {, attr} |

         WHERE CURRENT OF |cursor_name       |;
                          |emptrig_cursor_new|
`table_name` | テーブル名
`attr` | 更新するアトリビュート名
`variable` | オプションとして制御変数を指定することが可能な変数
`cursor_name` | カーソルのプリコンパイラ識別子(カーソル名)
`emptrig_cursor_new` | トリガーで使用する予約されたカーソルのプリコンパイラ識別子
SQLCODE |
`0` | 正常です。
`1` | レコードはロックされています。
`-78` | readモードでオープンされているカーソルを更新しようとしました。
`-79` | カーソルは単一テーブルで構成しなくてはなりません。
`-80` | 間違ったテーブル名です。
`-81` | 集計関数を含むカーソルです。
`-83` | 間違ったアトリビュート名です。
`-84` | `UPDATE`ステートメントは失敗しました。
`-85` | 間違ったデータタイプの変数です。
注意 | カーソルは複数のテーブルの参照はしないようにしてください。 カーソルは、集計関数を含めないようにしてください。 `table_name` または `CURRENT`キーワードは、 テーブルを参照するために使用することができます。 `emptrig_cursor_old`は、`UPDATE`コマンド中で 使用することはできません。 `AFTER INSERT`、`AFTER UPDATE`および`AFTER DELETE` トリガー内で発行される`UPDATE`コマンドは、 PSM プロシージャ中で使用する場合、効果が得られないことに注意してください。 予約されたプリコンパイラカーソル識別子`emptrig_cursor_old`と `emptrig_cursor_new`は、トリガーPSMプロシージャ内のみで使用することが できます。
例 1 | 以下のコマンドは、テーブル`tab1`を更新します。 カーソル`ct1`のカレントのレコードのname アトリビュートに 文字列'`Jerry`'を割り付けます。
       strcpy (name_var, "Jerry");
       EXEC SQL UPDATE tab1 SET name = :name_var WHERE CURRENT OF ct1;
例 2 | 以下のコマンドは、テーブル`acid_tests`を更新します。 カーソル`c1`のカレントのレコードの アトリビュート`color_change`に文字列'`black`'を割り付け、 アトリビュート`reaction_time`に整数値 7 セットします。
       strcpy (tab, "acid_tests");
       strcpy (att1, "color_change");
       strcpy (att2, "reaction_time");
       strcpy (str1, "black");
       val2 = 7;
       EXEC SQL UPDATE :tab SET :att1 = :str1, :att2 = :val2
       WHERE CURRENT OF c1;