コンテンツフレーム起動

カーソルを使用したデータの読込 文書を SAP ライブラリストラクチャに組み込む

通常の SELECT 命令では、SELECT 命令中に INTO 句で指定された対象領域に、選択からのデータが常に直接読み込まれます。カーソルを使ってデータを読み込むと、SELECT 命令からプロセスが分離されます。これを行うには、SELECT 命令でカーソルをオープンする必要があります。その後、選択からの行をフラット対象領域に配置することができます。

カーソルのオープンとクローズ

SELECT 命令に対してカーソルをオープンするには、以下を使用します。

OPEN CURSOR [WITH HOLD] <c> FOR SELECT      < 結果 >
                                  FROM      <
ソース >
                                  [WHERE    <
条件 >]
                                  [GROUP BY <
項目 >]
                                  [HAVING   <cond>]
                                  [ORDER BY <
項目 >].

まず、DATA 命令と特殊データ型 CURSOR を使用してカーソル <C> を宣言します。SELECT 命令の INTO 句以外のすべての句を使用することができます。さらに、選択に複数の行が含まれるように、SELECT だけを指定することができます。つまり、SINGLE オプションを使用せず、列選択に集合式だけが含まれるようにしないということです。

オープンカーソルは、オブジェクトを指す参照変数と同様に、内部ハンドラを指します。カーソルを再割当して、複数のカーソルが同じハンドラを指すようにすることができます。MOVE 命令では、対象カーソルはソースカーソルのすべての属性 ( 特に位置) および OPEN CURSOR 命令のすべての句を採用します。

また、単一のデータベーステーブルに対して複数のカーソルを並行してオープンすることができます。カーソルがすでにオープンしている場合、再度オープンすることはできません。カーソルを明示的に 閉じる には、以下の命令を使用します。

CLOSE CURSOR <c>.

同時にオープンするカーソルの数は限られているため、この命令は不要になったすべてのカーソルを閉じるために使用します。1 つの例外を除いて、カーソルを明示的または黙示的に閉じるときにデータベース LUW が終了します。OPEN CURSOR 命令の WITH HOLD オプションによって、ネイティブ SQL でデータベースコミットが行なわれたときにカーソルが閉じないようにすることができます。

データの読込

オープンカーソルはデータベーステーブルの複数行選択にリンクされています。データを ABAP プログラムの対象領域に読み込むには、以下を使用します。

FETCH NEXT CURSOR <c> INTO < 対象 >.

これにより、選択の 1 つの行が対象領域 < 対象> に書き込まれ、選択セット内でカーソルが 1 行分移動します。フェッチ命令は、SELECT 命令の他の句から INTO を分離します。SELECT 命令の INTO 句はすべて使用することができます。命令は、INTO 句の対象領域に書き込むために必要な行を読み込み、カーソルを次の読み込む行に移動します。

選択のすべての行が読み込まれるまで SY-SUBRC 0 に設定します。それ以外の場合は 4 です。FETCH 命令の後、システム項目SY-DBCNT には該当カーソルに対してこれまで読み込まれたすべての行数が含まれます。

例

REPORT demo_select_cursor_1.

DATA: c1 TYPE cursor,
      c2 TYPE cursor.

DATA: wa1 TYPE spfli,
      wa2 TYPE spfli.

DATA: flag1(1) TYPE c,
      flag2(1) TYPE c.

OPEN CURSOR: c1 FOR SELECT  carrid connid
                      FROM  spfli
                      WHERE carrid = 'LH',

             c2 FOR SELECT  carrid connid cityfrom cityto
                      FROM  spfli
                      WHERE carrid = 'AZ'.

DO.
  IF flag1 NE 'X'.

     FETCH NEXT CURSOR c1 INTO CORRESPONDING FIELDS OF wa1.
     IF sy-subrc <> 0.
      CLOSE CURSOR c1.

       flag1 = 'X'.
ELSE.
       WRITE: / wa1-carrid, wa1-connid.
ENDIF.
ENDIF.
  IF flag2 NE 'X'.

     FETCH NEXT CURSOR c2 INTO CORRESPONDING FIELDS OF wa2.
     IF sy-subrc <> 0.
      CLOSE CURSOR c2.

       flag2 = 'X'.
ELSE.
       WRITE: / wa2-carrid, wa2-connid,
               wa2-cityfrom, wa2-cityto.
ENDIF.
ENDIF.
  IF flag1 = 'X' AND flag2 = 'X'.

EXIT.
ENDIF.
ENDDO.

出力結果は以下のようになります。

このグラフィックは添付のテキストに説明されています

データベーステーブル SPFLI は、それぞれ異なる条件を持つ 2 つのカーソルを使用して読み込まれます。選択された行は代わりに DO ループに読み込まれます。

例

REPORT demo_select_cursor_2.

DATA c TYPE cursor.

DATA wa TYPE sbook.

OPEN CURSOR c FOR SELECT     carrid connid fldate bookid smoker
                    FROM     sbook
                    ORDER BY carrid connid fldate smoker bookid.

FETCH NEXT CURSOR c INTO CORRESPONDING FIELDS OF wa.

WHILE sy-subrc = 0.
  IF wa-smoker = ' '.

     PERFORM nonsmoker USING c.
  ELSEIF wa-smoker = 'X'.

     PERFORM smoker USING c.
    SKIP.
ELSE.
EXIT.
ENDIF.
ENDWHILE.

FORM nonsmoker USING n_cur TYPE cursor.
   WHILE wa-smoker = ' ' AND sy-subrc = 0.
    FORMAT COLOR = 5.
    WRITE: / wa-carrid, wa-connid, wa-fldate, wa-bookid.

     FETCH NEXT CURSOR n_cur INTO CORRESPONDING FIELDS OF wa.
ENDWHILE.
ENDFORM.

FORM smoker USING s_cur TYPE cursor.
   WHILE wa-smoker = 'X' AND sy-subrc = 0.
    FORMAT COLOR = 6.
    WRITE: / wa-carrid, wa-connid, wa-fldate, wa-bookid.

     FETCH NEXT CURSOR s_cur INTO CORRESPONDING FIELDS OF wa.
ENDWHILE.
ENDFORM.

以下は一覧照会からの抜粋です。

このグラフィックは添付のテキストに説明されています

プログラムによって、データベーステーブル SBOOK のカーソルがオープンされます。最初の FETCH 命令の後、SMOKER 列の内容に依存するサブルーチンが呼び出されます。カーソルはサブルーチンのインタフェースパラメータに渡されます。サブルーチンは、SMOKER 列の内容が変更されるまで行を読み込みます。サブルーチンは、カーソルによって読み込まれた行を使用すると異なるタスクを実行します。

例

REPORT demo_select_cursor_3.

DATA: wa_spfli   TYPE spfli,
      wa_sflight TYPE sflight,
      wa_sflight_back TYPE sflight.

DATA: c1 TYPE cursor,
      c2 TYPE cursor.

OPEN CURSOR c1 FOR     SELECT *
                 FROM  spfli
                 ORDER BY PRIMARY KEY.

OPEN CURSOR c2 FOR     SELECT *
                 FROM  sflight
                 ORDER BY PRIMARY KEY.

DO.
  FETCH NEXT CURSOR c1 INTO wa_spfli.

   IF sy-subrc NE 0.
    EXIT.
ENDIF.
  WRITE: / wa_spfli-carrid, wa_spfli-connid.

   DO.
    IF NOT wa_sflight_back IS INITIAL.

       wa_sflight = wa_sflight_back.
       CLEAR wa_sflight_back.
ELSE.
      FETCH NEXT CURSOR c2 INTO wa_sflight.

   IF sy-subrc <> 0.
    EXIT.

       ELSEIF wa_sflight-carrid <> wa_spfli-carrid
          OR wa_sflight-connid <> wa_spfli-connid.

         wa_sflight_back = wa_sflight.
EXIT.
ENDIF.
ENDIF.
    WRITE: / wa_sflight-carrid, wa_sflight-connid,
             wa_sflight-fldate.
ENDDO.
ENDDO.

出力結果は以下のとおりです。

このグラフィックは添付のテキストに説明されています

プログラムによって、テーブル SPFLI および SFLIGHT のそれぞれに対するカーソルがオープンされます。2 つのテーブルは外部キー関係によってリンクされているため、選択を一次キーでソートすることによってネストループをプログラムして、内部ループで読み込まれたデータが外部ループのデータに依存するようにすることができます。このプログラムメソッドは、内部ループのカーソルを続けて再オープンする必要がないため、ネストされた SELECT 命令を使用するよりも速く実行できます。内部ループのグループレベルが変更された場合は、カーソルをリセットすることができないため、次のループが渡されるまで読み込まれるデータが一時的に保存されます。

 

 

 

 

コンテンツフレーム終了