Oracle PL/SQL カーソル

カーソルとは、Oracle PL/SQLにおいてSQLのDML文(SELECTINSERTUPDATEDELETE及びMERGE)の処理に関する情報を保管した領域である。カーソルには「暗黙カーソル」と「明示カーソル」の2種類がある。

暗黙カーソル

暗黙カーソルとは、明示的にカーソルの使用を宣言することなく使えるカーソルである。暗黙カーソルは最後に実行したDML文の状態を保持する。

カーソルには属性があり、DML文の実行に関する情報を保持している。

暗黙カーソルの属性
カーソル属性 説明
SQL%FOUND INSERT文、UPDATE文又はDELETE文でひとつ以上の行に影響を与えた場合又はSELECT INTO文がひとつ以上の行を戻した場合、SQL%FOUND属性がTRUEになる。それ以外の場合はSQL%FOUND属性がFALSEになる。
SQL%ISOPEN 本来はカーソルがオープンされているかどうかを表す属性であるが、暗黙カーソルはDML文を実行する際に自動的にオープンされ、DML文の実行が終了すると自動的にクローズされるため、SQL%ISOPEN属性は常にFALSEである。
SQL%NOTFOUND INSERT文、UPDATE文又はDELETE文がどの行にも影響を与えなかった場合又はSELECT INTO文がどの行戻さなかった場合にSQL%NOTFOUND属性がTRUEになる。それ以外の場合はSQL%NOTFOUND属性がFALSEになる。
SQL%ROWCOUNT INSERT文、UPDATE文又はDELETE文が影響を与えた行又はSELECT INTO文に戻された行の数を表す。

明示カーソル

明示カーソルとは、明示的にカーソルを宣言してから使用するカーソルである。暗黙カーソルは最後に実行したDML文の状態を保持するのに対して、明示カーソルはそれぞれのDML文ごとに異なるカーソルを作成できる。

次に明示カーソルの属性を示す。cursorはカーソル名を表している。

明示カーソルの属性
カーソル属性 説明
cursor%ISOPEN カーソルがオープンされている(TRUE)か、カーソルがオープンされていない(FALSE)か。
cursor%FOUND 直前のフェッチが行を戻した(TRUE)か、直前のフェッチが行を戻さなかった(FALSE)か、カーソルがオープンされてからまだフェッチされていない(NULL)か。
cursor%NOTFOUND 直前のフェッチが行を戻さなかった(TRUE)か、直前のフェッチが行を戻した(FALSE)か、カーソルがオープンされてからまだフェッチされていない(NULL)か。
cursor%ROWCOUNT これまでにフェッチした行数。カーソルをオープンした状態では0であり、フェッチで行が戻されるたびに数値が増加する。

カーソルの宣言

明示カーソルを使用するには、まずカーソルを宣言する必要がある。カーソルを宣言する構文を次に示す。

CURSOR cursor[(paramlist)] [RETURN return_type] IS select_query
cursor
カーソルの名前
paramlist
カーソルのパラメータを次の構文で指定する。
parameter_name [IN] datatype [{ := | DEFAULT } expr]
parameter_name
パラメータの名前
datatype
パラメータのデータ型
expr
パラメータの初期値
return_type
戻り値のデータ型
select_query
SELECT文

カーソルを宣言する例を示す。

CURSOR csr1 IS SELECT empno, ename FROM employee WHERE salary > 3000;
CURSOR csr2 RETURN employee%ROWTYPE IS SELECT * FROM employee WHERE deptno = 4;
CURSOR csr3 (p_sal NUMBER DEFAULT 0) IS SELECT * FROM employee WHERE salary > p_sal;

カーソルをオープンする

OPEN cursor[(paramlist)]
cursor

オープンするカーソルの名前を指定する。

paramlist

カーソルの引数をカンマで区切ったリストを指定する。

カーソルをクローズする

CLOSE cursor
cursor

クローズするカーソルの名前を指定する。

FETCH

カーソルを利用したフェッチを行なうには FETCH 文を使用する。

FETCH カーソル名 INTO 変数名 ;
LOOP
FETCH csr1 INTO my_record;
EXIT WHEN csr1%NOTFOUND;
-- データレコード処理
END LOOP;

結果セットや問い合わせの中の変数の値を変更する場合は、カーソルをクローズし、入力変数を新しい値にして、もう一度オープンする必要がある。

FOR

カーソルを使った繰り返し処理としてカーソルFORループがある。カーソルFORループを使えば、カーソルのオープン、カーソルのクローズ、繰り返し処理の終了条件は省略することができる。

FOR record IN cursor LOOP
  -- 繰り返し処理
END LOOP;
FOR record IN cursor(param [,param...]) LOOP
  -- 繰り返し処理
END LOOP;
record
レコード名。暗黙的に宣言されているので、あらかじめ宣言部で明示的に宣言する必要はない。
cursor
カーソル名
param

カーソルに渡す引数

カーソル FOR ループ内で record_name . column_name で列の値を参照することができる。