行記憶域を使用した複数行 FETCH

複数行用 FETCH ステートメントを行記憶域とともに使用するには、その前にアプリケーションで、行記憶域および関連した記述域を定義しなければなりません。

行記憶域とは、アプリケーションで定義されるホスト変数のことです。 この行記憶域には、複数行用 FETCH ステートメントの結果が入ります。 行記憶域は、複数行用 FETCH ステートメントで要求された行をすべて収容できるだけの十分なバイト数を持つ文字変数でも構いません。

行記憶域形式の複数行用 FETCH で使用される関連記述子では、返される各列の SQLTYPE と SQLLEN が入る SQLDA を定義します。 記述子に指定する情報によって、データベースから行記憶域へのデータ・マッピングが判別されます。パフォーマンスを最高にするには、記述子に指定されている属性情報が、取り出される列の属性と一致していなければなりません。

次の PL/I の例を検討してください。

注: コード例を使用する場合は、コードに関するライセンス情報および特記事項のご使用条件に同意する必要があります。
       *....+....1....+....2....+....3....+....4....+....5....+....6....+....7...*
     EXEC SQL INCLUDE SQLCA;
     EXEC SQL INCLUDE SQLDA;
 
...
 
    DCL DEPTPTR PTR;
    DCL 1 DEPT(20) BASED(DEPTPTR),
        3 EMPNO CHAR(6),
        3 LASTNAME CHAR(15) VARYING,
        3 WORKDEPT CHAR(3),
        3 JOB CHAR(8);
    DCL I BIN(31) FIXED;
    DEC J BIN(31) FIXED;
    DCL ROWAREA CHAR(2000);
 
...
 
    ALLOCATE SQLDA SET(SQLDAPTR);
    EXEC SQL
     DECLARE D11 CURSOR FOR
     SELECT EMPNO, LASTNAME, WORKDEPT, JOB
     FROM CORPDATA.EMPLOYEE
     WHERE WORKDEPT = 'D11';
 
...
 
    EXEC SQL
      OPEN D11;
    /* SET UP THE DESCRIPTOR FOR THE MULTIPLE-ROW FETCH */
    /* 4 COLUMNS ARE BEING FETCHED                 */
    SQLD = 4;
    SQLN = 4;
    SQLDABC = 366;
    SQLTYPE(1) = 452; /* FIXED LENGTH CHARACTER -  */
                      /* NOT NULLABLE              */
    SQLLEN(1) = 6;
    SQLTYPE(2) = 456; /*VARYING LENGTH CHARACTER   */
                      /* NOT NULLABLE              */
    SQLLEN(2) = 15;
    SQLTYPE(3) = 452; /* FIXED LENGTH CHARACTER -  */
    SQLLEN(3) = 3;
    SQLTYPE(4) = 452; /* FIXED LENGTH CHARACTER -  */
                      /* NOT NULLABLE              */
    SQLLEN(4) = 8;
    /*ISSUE THE MULTIPLE-ROW FETCH STATEMENT TO RETRIEVE*/
    /*THE DATA INTO THE DEPT ROW STORAGE AREA      */
    /*USE A HOST VARIABLE TO CONTAIN THE COUNT OF  */
    /*ROWS TO BE RETURNED ON THE MULTIPLE-ROW FETCH     */
 
    J = 20;        /*REQUESTS 20 ROWS ON THE FETCH */
   ...
    EXEC SQL
      WHENEVER NOT FOUND
      GOTO FINISHED;
    EXEC SQL
      WHENEVER SQLERROR
      GOTO FINISHED;
    EXEC SQL
      FETCH D11 FOR :J ROWS
      USING DESCRIPTOR :SQLDA INTO :ROWAREA;
    /* ADDRESS THE ROWS RETURNED                   */
    DEPTPTR = ADDR(ROWAREA);
    /*PROCESS EACH ROW RETURNED IN THE ROW STORAGE */
    /*AREA BASED ON THE COUNT OF RECORDS RETURNED  */
    /*IN SQLERRD3.                                 */
    DO I = 1 TO SQLERRD(3);
     IF EMPNO(I) = '000170'  THEN
       DO;
      :
       END;
    END;
    IF SQLERRD(5) = 100 THEN
      DO;
        /* PROCESS END OF FILE  */
      END;
    FINISHED:
 

この例では、カーソルは、CORPDATA.EMPLOYEE 表で WORKDEPT 列が 'D11' に等しいすべての行を選択するように定義されています。 サンプル表に記載されているサンプルの EMPLOYEE 表の例では、結果表に複数行が入ることが示されています。 DECLARE CURSOR ステートメントと OPEN ステートメントには、複数行用 FETCH ステートメントとともに使用する場合の特殊な構文はありません。 同じカーソルに対して 1 つの行を返す別の FETCH ステートメントをプログラム内のほかの場所にコーディングすることができます。 複数行用 FETCH ステートメントは、結果表にすべての行を取り出すために使用されます。 FETCH の実行後、カーソルはブロック内の最終行に置かれたままになります。

行記憶域 ROWAREA は、文字配列として定義されています。結果表から取り出されたデータは、ホスト変数に入ります。この例では、ROWAREA のアドレスにポインター変数が割り当てられています。返される行内の各項目が検査され、基底付き構造 DEPT で使われます。

記述子の項目の属性 (タイプと長さ) は、取り出される列と一致しています。このケースでは、標識区域は指定されていません。

FETCH ステートメントが完了すると、ROWAREA には 'D11' と等しいすべての行 (この例では 11 行) が入ります。アプリケーションに返される SQLCA には、次の情報が入ります。

  • SQLCODE には、0 が入ります。
  • SQLSTATE には '00000' が入ります。
  • SQLERRD3 には、返される行数を示す 11 が入ります。
  • SQLERRD4 には、取り出される行の長さを示す 34 が入ります。
  • SQLERRD5 には、結果表の最後の行が取り出されたことを示す +100 が入ります。

この例では、アプリケーションは、ファイルの終わりに達したことを示す標識が SQLERRD5 に入るということを利用しています。 その結果、このアプリケーションでは、さらに行の取り出しを試みるためにもう一度 SQL を呼び出す必要がありません。カーソルが挿入を即時に感知する場合は、レコードが追加されたときに SQL を呼び出す必要があります。カーソルが即時感知性を持つのは、コミットメント制御レベルが *RR 以外である場合です。