ヘッダーをスキップ

Oracle Rdb SQLリファレンス・マニュアル リリース7.2 E06178-01 |
| 目次 | 索引

戻る | 次へ |

    SQL> -- Define a cursor of Board Manufacturing Department Managers:
    SQL> --
    SQL> DECLARE BM_MGR CURSOR FOR
    cont> SELECT EMPLOYEE_ID, RESUME FROM RESUMES R, CURRENT_INFO CI
    cont> WHERE R.EMPLOYEE_ID = CI.ID AND DEPARTMENT
    cont> CONTAINING "BOARD MANUFACTURING" AND JOB = "Department Manager";
    SQL> --
    SQL> -- Define a cursor for resumes of those managers:
    SQL> DECLARE THE_RESUME LIST CURSOR FOR
    cont> SELECT RESUME WHERE CURRENT OF BM_MGR;
    SQL> --
    SQL> -- Build the manager's cursor:
    SQL> OPEN BM_MGR;
    SQL> --
    SQL> -- Fetch the manager's row:
    SQL> FETCH BM_MGR;
     R.EMPLOYEE_ID   R.RESUME
     00164                           72:2:3
    SQL> --
    SQL> -- Get part of the resume:
    SQL> OPEN THE_RESUME;
    SQL> FETCH THE_RESUME;
     RESUME
     This is the resume for Alvin Toliver
    SQL> --
    SQL> -- Do not close the resume, and access the next manager:
    SQL> FETCH BM_MGR;
     R.EMPLOYEE_ID   R.RESUME
     00166                           72:2:9
    SQL> -- SQL continues to fetch from Toliver's resume (00164)
    SQL> -- because the list cursor was not closed.
    SQL> -- If it were a new resume, you would see
    SQL> -- a new "This is the resume for ..." line.
    SQL> FETCH THE_RESUME;
     RESUME
     Boston, MA

- 宣言カーソルは、TSET TRANSACTION RESERVING句またはLOCK TABLE文で指定された同じ表または表のリストを参照する必要があります。次に例を示します。

      SQL> SET TRANSACTION RESERVING jobs FOR WRITE;
      SQL> DECLARE curs1 CURSOR WITH HOLD FOR
      cont> SELECT first_name,last_name FROM employees;
      SQL> OPEN CURS1;
      %RDB-E-UNRES_REL, relation EMPLOYEES in specified request is not a relation
      reserved in specified transaction

- 表カーソルにはWITH HOLD句のみを指定できます。

- 一部の問合せでは、RdbはOPEN文の実行時にカーソル用のデータをプリフェッチできます。例にはORDER BY句を含むカーソルがあります。ORDER BY句では、結果の最初の行を配布する前にデータを読み取ってソートする必要があります。フェッチされた行はここではOPEN時のデータのスナップショットになり、COMMIT文の実行後は不要になることがあります。
  たとえば、ユーザーBROWNが従業員表にアクセスするカーソルを宣言およびオープンし、後でトランザクションをコミットしますが、WITH HOLDカーソルをオープンしたままとします。BROWNがカーソルをオープンしているときに、ユーザーJONESが従業員表からある従業員を削除します。BROWNにはまだJONESによって削除された従業員が表示されています。BROWNは元の状態の表からの一時コピーにアクセスしているためです。

- SET HOLD CURSORS文を使用して、保持可能カーソルのSQLセッションのデフォルト設定を定義できます。詳細は、「SET HOLD CURSORS文」を参照してください。

- WITH HOLD PRESERVE ALL句は、カーソルのODBCドライバの動作に準拠しています。

- アウトラインが存在する場合は、OPTIMIZE USING句で指定されているアウトラインが使用されます。ただし、アウトラインのディレクティブを1つ以上順守できない場合は除きます。たとえば、アウトラインの準拠レベルが必須で、アウトラインのディレクティブで指定されている索引の1つが削除された場合、そのアウトラインは使用されません。既存のアウトラインを使用できない場合は、エラー・メッセージが発行されます。
  存在しないアウトラインの名前を指定すると、問合せがコンパイルされ、そのアウトライン名は無視され、問合せと同じアウトラインIDを持つ既存のアウトラインが検索されます。同じアウトラインIDのアウトラインが検出されると、そのアウトラインのディレクティブを使用して問合せを実行しようとします。同じアウトラインIDを持つアウトラインが検出されない場合、問合せ実行のための計画がオプティマイザで選択されます。
  問合せアウトラインの詳細は、『Oracle Rdb7 Guide to Database Performance and Tuning』を参照してください。

  ## 例

  > 例1: 対話型SQLにおける表カーソルの宣言

  > 次の例は、SALARY_INFOというカーソルを宣言しています。SALARY_INFOの結果表には、従業員の名前および現在の給与が格納され、姓でソートされています。

  >     SQL> --
  >     SQL> DECLARE SALARY_INFO CURSOR FOR
  >     cont>  SELECT  E.FIRST_NAME, E.LAST_NAME, S.SALARY_AMOUNT
  >     cont>  FROM    EMPLOYEES E, SALARY_HISTORY S
  >     cont>  WHERE   E.EMPLOYEE_ID = S.EMPLOYEE_ID
  >     cont>          AND
  >     cont>          S.SALARY_END IS NULL
  >     cont>  ORDER BY
  >     cont>          E.LAST_NAME ASC;
  >     SQL> --
  >     SQL> -- Use an OPEN statement to open the cursor and
  >     SQL> -- position it before the first row of the
  >     SQL> -- result table:
  >     SQL> OPEN SALARY_INFO;
  >     SQL> --
  >     SQL> -- Finally, use two FETCH statements to see the
  >     SQL> -- first two rows of the cursor:
  >     SQL> FETCH SALARY_INFO;
  >      E.FIRST_NAME   E.LAST_NAME      S.SALARY_AMOUNT
  >      Louie          Ames                  $26,743.00
  >     SQL> FETCH SALARY_INFO;
  >      E.FIRST_NAME   E.LAST_NAME      S.SALARY_AMOUNT
  >      Leslie         Andriola              $50,424.00

  > 例2: Cプログラムにおける表カーソルの宣言

  > この単純なプログラムでは埋め込まれたDECLARE CURSOR文、OPEN文およびFETCH文が使用され、マネージャの名前および部門が取得および出力されます。

  >     #include <stdio.h>

  >     void main ()
  >     {
  >     int SQLCODE;
  >     char FNAME[15];
  >     char LNAME[15];
  >     char DNAME[31];

  >     /* Declare the cursor: */
  >     exec sql
  >         DECLARE MANAGER CURSOR FOR
  >             SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME
  >             FROM EMPLOYEES E, DEPARTMENTS D
  >             WHERE E.EMPLOYEE_ID = D.MANAGER_ID ;

  >     /* Open the cursor: */
  >     exec sql
  >         OPEN MANAGER;

  >     /* Start a loop to process the rows of the cursor: */
  >     for (;;)
  >         {
  >         /* Retrieve the rows of the cursor
  >         and put the value in host language variables: */
  >         exec sql
  >             FETCH MANAGER INTO :FNAME, :LNAME, :DNAME;
  >         if (SQLCODE != 0) break;
  >         /* Print the values in the variables: */
  >         printf ("%s %s %s\n", FNAME, LNAME, DNAME);
  >         }

  >     /* Close the cursor: */
  >     exec sql
  >         CLOSE MANAGER;
  >     }

  > 例3: 対話型SQLにおける表カーソルおよびリスト・カーソルを使用したリスト・データの取得

  > 次の例は、リスト情報を取得する表カーソルおよびリスト・カーソルを宣言しています。

  >     SQL> DECLARE TBLCURSOR INSERT ONLY TABLE CURSOR FOR
  >     cont> SELECT EMPLOYEE_ID, RESUME FROM RESUMES;
  >     SQL> DECLARE LSTCURSOR INSERT ONLY LIST CURSOR FOR SELECT RESUME WHERE
  >     CURRENT OF TBLCURSOR;
  >     SQL> OPEN TBLCURSOR;
  >     SQL> INSERT INTO CURSOR TBLCURSOR (EMPLOYEE_ID) VALUES ('00164');
  >     1 row inserted
  >     SQL> OPEN LSTCURSOR;
  >     SQL> INSERT INTO CURSOR LSTCURSOR VALUES ('This is the resume for 00164');
  >     SQL> INSERT INTO CURSOR LSTCURSOR VALUES ('Boston, MA');
  >     SQL> INSERT INTO CURSOR LSTCURSOR VALUES ('Oracle Corporation');
  >     SQL> CLOSE LSTCURSOR;
  >     SQL> CLOSE TBLCURSOR;
  >     SQL> COMMIT;
  >     SQL> DECLARE TBLCURSOR2 CURSOR FOR SELECT EMPLOYEE_ID,
  >     cont> RESUME FROM RESUMES;
  >     SQL> DECLARE LSTCURSOR2 LIST CURSOR FOR SELECT RESUME WHERE
  >     CURRENT OF TBLCURSOR2;
  >     SQL> OPEN TBLCURSOR2;
  >     SQL> FETCH TBLCURSOR2;
  >       00164
  >     SQL> OPEN LSTCURSOR2;
  >     SQL> FETCH LSTCURSOR2;
  >      RESUME
  >      This is the resume for 00164
  >     SQL> FETCH LSTCURSOR2;
  >      RESUME
  >      Boston, MA
  >     SQL> FETCH LSTCURSOR2;
  >      RESUME
  >      Oracle Corporation
  >     SQL> FETCH LSTCURSOR2;
  >      RESUME
  >     %RDB-E-STREAM_EOF, attempt to fetch past end of record stream
  >     SQL> CLOSE LSTCURSOR2;
  >     SQL> SELECT * FROM RESUMES;
  >       EMPLOYEE_ID    RESUME
  >      00164                     1:701:2
  >     1 row selected
  >     SQL> CLOSE TBLCURSOR2;
  >     SQL> COMMIT;

  > 例4: リスト・カーソルのスクロール属性の使用

  > 次の例は、表カーソルおよび読取り専用スクロール可能リスト・カーソルを宣言し、リストのセグメント間を前後にスクロールすることによってリスト情報を取得しています。

  >     SQL> DECLARE CURSOR_ONE
  >     cont>   TABLE CURSOR FOR
  >     cont>   (SELECT EMPLOYEE_ID,RESUME FROM RESUMES);
  >     SQL> --
  >     SQL> DECLARE CURSOR_TWO
  >     cont>    READ ONLY
  >     cont>    SCROLL
  >     cont>    LIST CURSOR
  >     cont>    FOR SELECT RESUME
  >     cont>    WHERE CURRENT OF CURSOR_ONE;

  > 例5: 保持可能カーソルの宣言

  >     SQL> -- Declare a holdable cursor that remains open on COMMIT
  >     SQL> --
  >     SQL> DECLARE curs1 CURSOR
  >     cont>     WITH HOLD PRESERVE ON COMMIT
  >     cont>     FOR SELECT e.first_name, e.last_name
  >     cont>         FROM employees e
  >     cont>         ORDER BY e.last_name;
  >     SQL> OPEN curs1;
  >     SQL> FETCH curs1;
  >      FIRST_NAME   LAST_NAME
  >      Louie        Ames
  >     SQL> FETCH curs1;
  >      FIRST_NAME   LAST_NAME
  >      Leslie       Andriola
  >     SQL> COMMIT;
  >     SQL> FETCH curs1;
  >      FIRST_NAME   LAST_NAME
  >      Joseph       Babbin
  >     SQL> FETCH curs1;
  >      FIRST_NAME   LAST_NAME
  >      Dean         Bartlett
  >     SQL> ROLLBACK;
  >     SQL> FETCH curs1;
  >     %SQL-F-CURNOTOPE, Cursor CURS1 is not opened
  >     SQL> --
  >     SQL> -- Declare another holdable cursor that remains open always
  >     SQL> --
  >     SQL> DECLARE curs2 CURSOR
  >     cont>     WITH HOLD PRESERVE ALL
  >     cont>     FOR SELECT e.first_name, e.last_name
  >     cont>         FROM employees e
  >     cont>         ORDER BY e.last_name;
  >     SQL> OPEN curs2;
  >     SQL> FETCH curs2;
  >      FIRST_NAME   LAST_NAME
  >      Louie        Ames
  >     SQL> FETCH curs2;
  >      FIRST_NAME   LAST_NAME
  >      Leslie       Andriola
  >     SQL> COMMIT;
  >     SQL> FETCH curs2;
  >      FIRST_NAME   LAST_NAME
  >      Joseph       Babbin
  >     SQL> FETCH curs2;
  >      FIRST_NAME   LAST_NAME
  >      Dean         Bartlett
  >     SQL> ROLLBACK;
  >     SQL> FETCH curs2;
  >      FIRST_NAME   LAST_NAME
  >      Wes          Bartlett

  # DECLARE CURSOR文、動的

  > 実行時にパラメータでSELECT文が指定されるカーソルを宣言します。

  > 動的および非動的の両方のDECLARE CURSOR文に適用される文要素の詳細は、「DECLARE CURSOR文」を参照してください。

  ## 環境

  > 動的DECLARE CURSOR文は次の環境で使用できます。

  > - プリコンパイル対象のホスト言語プログラムに埋め込まれる場合

  > - SQLモジュールのDECLARE文のセクションの一部として

  ## 形式

  ## 引数

  > ### cursor-name

  > 宣言するカーソルの名前です。モジュールのすべてのカーソル名の間で一意の名前を指定します。有効なSQL名を使用します。識別子の詳細は、第2.2節を参照してください。

  > ### FOR statement-name

  > 実行時に生成された、準備されたSELECT文を識別する名前です。

  > ### INSERT ONLY

  > 新規リストまたは新規行を作成またはオープンするように指定します。

  > ### LIST CURSOR

  > リスト内の要素にアクセスするカーソルを宣言していることを指定します。

  > ### PRESERVE ON COMMIT

  > ### PRESERVE ON ROLLBACK

  > ### PRESERVE ALL

  > ### PRESERVE NONE

  > カーソルがオープン状態を保持するタイミングを指定します。

  > - PRESERVE ON COMMIT
  >   コミット時に、WITH HOLD PRESERVE ON COMMIT構文で定義したものを除き、すべてのカーソルがクローズします。ロールバック時に、WITH HOLD PRESERVE ON COMMIT構文で定義したものを含めて、すべてのカーソルがクローズします。
  >   これは保存オプションなしでWITH HOLD句を指定することと同じです。

  > - PRESERVE ON ROLLBACK
  >   ロールバック時に、WITH HOLD PRESERVE ON ROLLBACK構文で定義したものを除き、すべてのカーソルがクローズします。コミット時に、WITH HOLD PRESERVE ON ROLLBACK構文で定義したものを含めて、すべてのカーソルがクローズします。

  > - PRESERVE ALL
  >   コミットまたはロールバックの後、すべてのカーソルがオープンしたままです。カーソルはCLOSE文の使用により、またはセッションの終了時に、クローズします。

  > - PRESERVE NONE
  >   すべてのカーソルがクローズするのは、CLOSE文、COMMIT文またはROLLBACK文の後の、プログラム停止時、または対話型SQL終了時です。
  >   これはWITH HOLD句を指定しないことと同じです。

  > ### READ ONLY

  > データベースの更新にカーソルが使用されないことを指定します。

  > ### SCROLL

  > Oracle Rdbでリストの項目をいずれかの方向（上下）またはランダムに読み取ることができることを指定します。

  > ### TABLE CURSOR

  > 表内の行にアクセスするカーソルを宣言していることを指定します。

  > ### UPDATE ONLY

  > データベースの更新にカーソルが使用されることを指定します。

  > ### WITH HOLD

  > カーソルがオープンしたままでトランザクションの終了後にその位置を保持することを指示します。これは保持可能カーソルと呼ばれます。

  ## 使用方法

  > - 動的DECLARE CURSOR文では、カーソル名はコンパイルされますが、SELECT文は実行時に確認されます。

  > - 動的DECLARE CURSOR文は非実行可能文であるため、この文は静的DECLARE CURSOR文と同様に、SQLモジュールのDECLAREセクションに配置する必要があります。

  > - 主問合せにGROUP BY句、UNION句、EXCEPT (MINUS)句またはINTERSECT句を含むカーソルおよびビューには、DBKEYによるアクセスを必要とする動的カーソルを使用してアクセスすることはできません。ユーザーが動的カーソルでこれらのビューのいずれかにアクセスしようとすると、カーソルのオープン時に次のエラーが返されます。

  >       "RDMS-F-VIEWNORET, view cannot be retrieved by database key".

  >   この問題を回避するには、非動的カーソルを使用してビューにアクセスします。動的カーソルを使用する必要がある場合は、文はビュー自体ではなく（必要に応じてGROUP BY句およびUNION句を指定して）ビューを構成する実表にアクセスする必要があります。

  > - 「DECLARE CURSOR文」の「使用方法」も参照してください。

  ## 例

  > 例1: 文名に対するパラメータの使用

  >        .
  >        .
  >        .
  >     * This program prepares a statement for dynamic execution from the string
  >     * passed to it, and uses a dynamic cursor to fetch a row from a table.
  >     *
  >     */
  >     #include <stdio.h>
  >     #include <descrip.h>

  >     struct SQLDA_STRUCT {
  >               char SQLDAID[8];
  >               int SQLDABC;
  >               short SQLN;
  >               short SQLD;
  >               struct {
  >                 short SQLTYPE;
  >                 short SQLLEN;
  >                 char *SQLDATA;
  >                 short *SQLIND;
  >                 short SQLNAME_LEN;
  >                 char SQLNAME[30];
  >                   } SQLVAR[];
  >             } *SQLDA;
  >     main()
  >     {

  >     /*
  >      *  General purpose locals
  >      */
  >     int     i;
  >     long    sqlcode;

  >     char    command_string[256];

  >     /*
  >      *  Allocate SQLDA structures.
  >      */

  >     SQLDA = malloc(500);
  >     SQLDA->SQLN = 20;

  >     /* Get the SELECT statement at run time. */

  >     printf("\n Enter a SELECT statement.\n");
  >     printf("\n Do not end the statement with a semicolon.\n");
  >     gets(command_string);

  >     /* Prepare the SELECT statement. */
  >     PREP_STMT( &sqlcode, &command_string, SQLDA );
  >     if (sqlcode != 0)
  >         goto err;

  >     /* Open the cursor. */
  >     OPEN_CURSOR( &sqlcode );
  >     if (sqlcode != 0)
  >         goto err;

  >     /* Allocate memory.   */
  >     for (i=0; i < SQLDA->SQLD; i++) {
  >         SQLDA->SQLVAR[i].SQLDATA = malloc( SQLDA->SQLVAR[i].SQLLEN );
  >         SQLDA->SQLVAR[i].SQLIND  = malloc( 2 );
  >     }

  >     /* Fetch a row. */
  >     FETCH_CURSOR( &sqlcode, SQLDA );
  >     if (sqlcode != 0)
  >         goto err;

  >     /* Use the SQLDA to determine the data type of each column in the row
  >        and print the column.  For simplicity, test for only two data types.
  >        CHAR and INT. */

  >     for (i=0; i < SQLDA->SQLD; i++) {

  >         switch (SQLDA->SQLVAR[i].SQLTYPE) {

  >         case SQLDA_CHAR;    /* Character */
  >             printf( "%s", SQLDA->SQLVAR[i].SQLDATA );
  >             break;
  >         case SQLDA_INTEGER:   /* Integer */
  >             printf( "%d", SQLDA->SQLVAR[i].SQLDATA );
  >             break;
  >         default:
  >             printf( "Some other datatype encountered\n");
  >         }
  >     }

  >     /* Close the cursor. */
  >     CLOSE_CURSOR( &sqlcode );

  >     ROLLBACK(&sqlcode );
  >     return;
  >        .
  >        .
  >        .
  >     }

  > 例2: プログラム・コールの前のSQLモジュール・ファイル

  >     --  This program uses dynamic cursors to fetch a row.
  >     --
  >     --
  >     MODULE          C_MOD_DYN_CURS
  >     LANGUAGE        C
  >     AUTHORIZATION   RDB$DBHANDLE

  >     DECLARE ALIAS FOR FILENAME personnel

  >     -- Declare the dynamic cursor. Use a statement name to identify a
  >     -- prepared SELECT statement.

  >     DECLARE CURSOR1 CURSOR FOR STMT_NAME

  >     -- Prepare the statement from a statement entered at run time
  >     -- and specify that SQL write information about the number and
  >     -- data type of select list items to the SQLDA.

  >     PROCEDURE PREP_STMT
  >         SQLCODE
  >         COMMAND_STRING  CHAR (256)
  >         SQLDA;

  >           PREPARE STMT_NAME SELECT LIST INTO SQLDA FROM COMMAND_STRING;

  >     PROCEDURE OPEN_CURSOR
  >          SQLCODE;

  >         OPEN CURSOR1;

  >     PROCEDURE FETCH_CURSOR
  >         SQLCODE
  >         SQLDA;

  >         FETCH CURSOR1 USING DESCRIPTOR SQLDA;

  >     PROCEDURE CLOSE_CURSOR
  >         SQLCODE;

  >         CLOSE CURSOR1;

  >     PROCEDURE ROLLBACK
  >         SQLCODE;

  >         ROLLBACK;

  # DECLARE CURSOR文、拡張動的

  > 拡張動的カーソルを宣言します。拡張動的DECLARE CURSOR文は、実行時にカーソル名とSELECT文の両方をパラメータに指定するDECLARE CURSOR文です。

  > 動的および非動的の両方のDECLARE CURSOR文に適用される文要素の詳細は、「DECLARE CURSOR文」を参照してください。

  ## 環境

  > 拡張動的DECLARE CURSOR文は次の環境で使用できます。

  > - プリコンパイル対象のホスト言語プログラムに埋め込まれる場合

  > - SQLモジュールのプロシージャの一部として

  ## 形式

  ## 引数

  > ### cursor-name-parameter

  > 宣言するカーソルの名前を格納します。文字列パラメータを使用して実行時にプログラムによって指定されるカーソル名を保持します。

  > ### FOR statement-id-parameter

  > 準備されたSELECT文を識別する整数を含むパラメータです。整数パラメータを使用して、PREPARE文の実行時に生成されてパラメータに割り当てられる文識別子を保持します。

  > ### INSERT ONLY

  > 新規リストまたは新規行を作成またはオープンするように指定します。

  > ### LIST CURSOR FOR

  > リスト内の要素にアクセスするカーソルを宣言していることを指定します。

  > ### PRESERVE ON COMMIT

  > ### PRESERVE ON ROLLBACK

  > ### PRESERVE ALL

  > ### PRESERVE NONE

  > カーソルがオープン状態を保持するタイミングを指定します。

  > - PRESERVE ON COMMIT
  >   コミット時に、WITH HOLD PRESERVE ON COMMIT構文で定義したものを除き、すべてのカーソルがクローズします。ロールバック時に、WITH HOLD PRESERVE ON COMMIT構文で定義したものを含めて、すべてのカーソルがクローズします。
  >   これは保存オプションなしでWITH HOLD句を指定することと同じです。

  > - PRESERVE ON ROLLBACK
  >   ロールバック時に、WITH HOLD PRESERVE ON ROLLBACK構文で定義したものを除き、すべてのカーソルがクローズします。コミット時に、WITH HOLD PRESERVE ON ROLLBACK構文で定義したものを含めて、すべてのカーソルがクローズします。

  > - PRESERVE ALL
  >   コミットまたはロールバックの後、すべてのカーソルがオープンしたままです。カーソルはCLOSE文の使用により、またはセッションの終了時に、クローズします。

  > - PRESERVE NONE
  >   すべてのカーソルがクローズするのは、CLOSE文、COMMIT文またはROLLBACK文の後の、プログラム停止時、または対話型SQL終了時です。
  >   これはWITH HOLD句を指定しないことと同じです。

  > ### READ ONLY

  > データベースの更新にカーソルが使用されないことを指定します。

  > ### SCROLL

  > Oracle Rdbでリストの項目をいずれかの方向（上下）またはランダムに読み取ることができることを指定します。

  > ### TABLE CURSOR FOR

  > 表内の行にアクセスするカーソルを宣言していることを指定します。

  > ### UPDATE ONLY

  > データベースの更新にカーソルが使用されることを指定します。

  > ### WITH HOLD

  > カーソルがオープンしたままでトランザクションの終了後にその位置を保持することを指示します。これは保持可能カーソルと呼ばれます。

  ## 使用方法

  > - 拡張動的DECLARE CURSOR文は、動的SQLの実行可能文です。パラメータを介して、カーソル名と、カーソルの実行時に元になるSELECT文の識別子の両方を指定できます。通常、拡張動的SQLを使用すると、1セットのSQLプロシージャは、任意の数の準備された文を同時に制御できます。

  > - 拡張動的DECLARE CURSOR文によって、複数の動的に生成されたSELECT文に対して1つのDECLARE CURSOR文とPREPARE文の組合せを使用できます。これによって、動的に生成された各SELECT文に対するDECLARE CURSOR文およびPREPARE文のコーディングが不要になります。

  > - 拡張動的DECLARE CURSOR文で、パラメータを使用してカーソル名と文識別子の両方を指定する必要があります。パラメータを介してカーソル名と文識別子の両方ではなくいずれか一方を明示的に指定すると、エラーが生成されます。カーソル名と文識別子の両方を明示的に指定すると、カーソルが非動的カーソルに、DECLARE CURSOR文が非実行可能文になります。

  > - 拡張動的DECLARE CURSOR文は実行可能文であるため、実行時に実行ステータス（SQLSTATEまたはSQLCODE）を返します。拡張動的DECLARE CURSOR文の実行後にプログラムでステータスをチェックする必要があります。
  >   拡張動的DECLARE CURSOR文は実行可能文であるため、実行可能文が使用できるプログラムおよびSQLモジュールに配置する必要があります。たとえば、拡張動的DECLARE CURSOR文は、静的または動的なDECLARE CURSOR文と同様に、DECLAREセクションではなく、SQLモジュールのプロシージャ内に配置する必要があります。

  > - 「DECLARE CURSOR文」の「使用方法」も参照してください。

  ## 例

  > 例1: 文名およびカーソル名に対するパラメータの使用

  > 次の例は、オンライン・サンプル・プログラムSQL$MULTI_STMT_DYN.SQLADAからの2つのプロシージャを示しています。このプロシージャは、文名およびカーソル名に対するパラメータの使用方法を示しています。

  >     .
  >     .
  >     .
  >     -- This procedure prepares a statement for dynamic execution from the string
  >     -- passed to it.  This procedure can prepare any number of statements
  >     -- because the statement is passed to it as the parameter, cur_procid.

  >     procedure PREPARE_SQL is
  >         CUR_CURSOR : string(1..31) := (others => ' ');
  >         CUR_PROCID : integer := 0;
  >         CUR_STMT : string(1..1024) := (others => ' ');

  >     begin
  >     -- Allocate separate SQLDAs for parameter markers (sqlda_in) and select list
  >     -- items (sqlda_out).  Assign the value of the constant MAXPARMS (set in the
  >     -- declarations section) to the SQLN field of both SQLDA structures. SQLN
  >     -- specifies to SQL the maximum size of the SQLDA.

  >     sqlda_in := new sqlda_record;
  >     sqlda_in.sqln := maxparms;
  >     sqlda_out := new sqlda_record;
  >     sqlda_out.sqln := maxparms;

  >     -- Assign the SQL statement that was constructed in the procedure
  >     -- CONSTRUCT_SQL to the variable cur_stmt.

  >     cur_stmt := sql_stmt;

  >     -- Use the PREPARE...SELECT LIST statement to prepare the dynamic statement
  >     -- and write information about any select list items in it to sqlda_out.
  >     -- It prepares a statement for dynamic execution from the string passed to
  >     -- it.  It also writes information about the number and data type of any
  >     -- select list items in the statement to an SQLDA (specifically, the
  >     -- sqlda_out SQLDA specified).
  >     --
  >     -- Note that the PREPARE statement could have prepared the statement without
  >     -- writing to an SQLDA.  Instead, a separate DESCRIBE...SELECT LIST statement
  >     -- would have written information about any select list items to an SQLDA.
  >     EXEC SQL PREPARE :cur_procid SELECT LIST INTO :sqlda_out FROM :cur_stmt;
  >     case sqlca.sqlcode is
  >         when sql_success => null;
  >         when others => raise syntax_error;
  >     end case;

  >     -- Use the DESCRIBE...MARKERS statement to write information about any
  >     -- parameter markers in the dynamic statement to sqlda_in.  This statement
  >     -- writes information to an SQLDA (specifically, the sqlda_in SQLDA
  >     -- specified) about the number and data type of any parameter markers in
  >     -- the prepared dynamic statement.  Note that SELECT statements may also
  >     -- have parameter markers.

  >     EXEC SQL DESCRIBE :cur_procid MARKERS INTO sqlda_in;
  >     case sqlca.sqlcode is
  >         when sql_success => null;
  >         when others => raise syntax_error;
  >     end case;

  >     -- If the operation is "Read," create a unique name for the cursor name
  >     -- so that the program can pass the cursor name to the dynamic DECLARE
  >     -- CURSOR statement.

  >     if cur_op(1) = 'R' then
  >         cur_cursor(1) := 'C';
  >         cur_cursor(2..name_strlng) := cur_name(1..name_strlng - 1);

  >     -- Declare the dynamic cursor.

  >         EXEC SQL DECLARE :cur_cursor CURSOR FOR :cur_procid;
  >         case sqlca.sqlcode is
  >             when sql_success => null;
  >             when others => raise syntax_error;
  >         end case;
  >     end if;

  >     number_of_procs := number_of_procs + 1;
  >     sqlda_in_array(number_of_procs) := sqlda_in;
  >     sqlda_out_array(number_of_procs) := sqlda_out;
  >     procedure_names(number_of_procs) := cur_name;
  >     procedure_ids(number_of_procs) := cur_procid;
  >     if cur_op(1) = 'R' then
  >         cursor_names(number_of_procs) := cur_cursor;
  >     end if;

  >     exception
  >         when syntax_error =>
  >             sql_get_error_text(get_error_buffer,get_error_length);
  >             put_line(get_error_buffer(1..integer(get_error_length)));
  >             put("Press RETURN to continue. ");
  >             get_line(terminal,release_screen,last);
  >             new_line;
  >     end PREPARE_SQL;
  >     .
  >     .
  >     .
  >     begin  -- procedure body DISPLAY_DATA

  >     -- Before displaying any data, allocate buffers to hold the data
  >     -- returned by SQL.
  >     --
  >         allocate_buffers;

  >     -- Allocate and assign SQLDAs for the requested SQL procedure.
  >     --
  >     sqlda_in := new sqlda_record;
  >     sqlda_in := sqlda_in_array(stmt_index);
  >     sqlda_out := new sqlda_record;
  >     sqlda_out := sqlda_out_array(stmt_index);
  >     cur_cursor := cursor_names(stmt_index);
  >     -- Open the previously declared cursor.  The statement specifies
  >     -- an SQLDA (specifically, sqlda_in) as the source of addresses for any
  >     -- parameter markers in the cursor's SELECT statement.
  >     --
  >     EXEC SQL OPEN :cur_cursor USING DESCRIPTOR sqlda_in;
  >     case sqlca.sqlcode is
  >         when sql_success => null;
  >         when others => raise unexpected_error;
  >     end case;

  >     -- Fetch the first row from the result table.  This statement fetches a
  >     -- row from the opened cursor and writes it to the addresses specified
  >     -- in an SQLDA (specifically, sqlda_out).
  >     --
  >     EXEC SQL FETCH :cur_cursor USING DESCRIPTOR sqlda_out;
  >     case sqlca.sqlcode is
  >     --  Check to see if the result table has any rows.
  >         when sql_success => null;
  >         when stream_eof =>
  >             put_line("No records found.");
  >             new_line;
  >         when others => raise unexpected_error;
  >     end case;

  >     -- Set up a loop to display the first row, then fetch and display second
  >     -- and subsequent rows.

  >         rowcount := 0;
  >         while sqlca.sqlcode = 0 loop
  >             rowcount := rowcount + 1;
  >     --      Execute the DISPLAY_ROW procedure.
  >             display_row;
  >     --      To only display 5 rows, exit the loop if the loop counter
  >     --      equals MAXROW (coded as 5 in this program).
  >             if rowcount = maxrows then exit; end if;
  >     --      Fetch another row, exit the loop if no more rows.
  >             EXEC SQL FETCH :cur_cursor USING DESCRIPTOR sqlda_out;
  >             case sqlca.sqlcode is
  >                 when sql_success => null;
  >                 when stream_eof => exit;
  >                 when others => raise unexpected_error;
  >             end case;
  >         end loop;
  >     -- Close the cursor.
  >     EXEC SQL CLOSE :cur_cursor;
  >     case sqlca.sqlcode is
  >         when sql_success => null;
  >         when others => raise unexpected_error;
  >     end case;
  >     exception
  >         when unexpected_error =>
  >             sql_get_error_text(get_error_buffer,get_error_length);
  >             EXEC SQL ROLLBACK;
  >             put_line("This condition was not expected.");
  >             put_line(get_error_buffer(1..integer(get_error_length)));
  >             put("Press RETURN to continue. ");
  >             get_line(terminal,release_screen,last);

  >     -- Stop and let the user look before returning.
  >         skip;
  >         put_line("Press RETURN to proceed. ");
  >         get_line(terminal,release_screen,last);

  >     end DISPLAY_DATA;