!--a11y-->

通常の 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 命令を使用するよりも速く実行できます。内部ループのグループレベルが変更された場合は、カーソルをリセットすることができないため、次のループが渡されるまで読み込まれるデータが一時的に保存されます。