😸

【PL/SQL】カーソルFORループ

2024/04/13に公開

PL/SQL初心者です。会社の研修でよく出ると先輩方から教わったので復習します。

カーソルとは

検索したデータを変数として格納する方法の一つでカーソルがあります。

カーソルについて簡単にいうと

PL/SQLのカーソルはデータベースからデータを一行ずつ取り出すための「目印」や「指標」のようなものです。
これにより、大量のデータがあっても一度にすべてを読み込む必要がなく、パソコンが重くなるのを防ぐことができます。
また、カーソルを使ってデータベースの中の各行に対して読み取り、更新、削除などの様々な処理を行うことができます。
まとめると、カーソルはデータベースの中を順番に移動しながら、必要な処理を行うことができます。

カーソルの使い方

カーソルは複数行を処理するだけあって処理が複雑です。
下記がカーソル処理の流れになります。

カーソル処理の流れ
DECLARE
   1.カーソルの定義
   ( CURSOR <カーソル名> IS <SELECT>BEGIN
   2. カーソルのオープン
   ( OPEN <カーソル名> )
 LOOP
   3. データの取り出し
      ( FETCH <カーソル名> INTO <変数名> )
 END LOOP;
    4. カーソルのクローズ
      ( CLOSE <カーソル名>END;

明示カーソルの制御

  1. カーソルに名前を付け、PL/SQLの宣言部にてカーソルを宣言。
  2. OPEN文により、カーソルに対応付けられた問い合わせを実行。結果セットを識別し、最初の行にカーソルを位置付けます。
  3. FETCH文により、現在行を取り出し、カーソルを次の行へと進めます。この処理は行が無くなるか、特定の条件を満たすまで続けられます。
  4. CLOSE文により、カーソルを開放。

今回は、明示カーソルの制御についてはざっくりとなりますが、処理にはこれだけの手順が必要になるということだけ頭に入れておきます。

カーソルFORループ

カーソルの処理は、上記のように複数の処理を踏む必要がありますが、カーソルFORループを使用することで以下の処理が自動化され、処理全体を単純化できます。

・ OPEN文、FETCH文、CLOSE文の指定
・ 取り出した行データを格納するための変数の定義

カーソルFORループの定義

指定されたカーソルが戻す行の型のレコード変数として暗黙的にループ索引を宣言し、カーソルをオープンします。反復されるたびに、カーソルFORループ文は、結果セットから行をフェッチしてレコードに入れます。

ループ索引とは

取り出されたデータが代入される変数です。
内部的には<カーソル名>%ROWTYPEで宣言されているため、代入された値は<ループ策引名>.<フィールド名>で参照できます。

PL/SQLのカーソルFORループは、SELECT文の結果セットを1行ずつ処理するための制御構造です。基本的な構文は下記のようになります。

基本的な構文
FOR ループ索引名 IN カーソル名 LOOP
  実行したい処理を記述
END LOOP;

カーソルFORループ使用例

具体的な実行例を下記に記します。

DECLARE
  CURSOR animal_cur IS
    SELECT id, name FROM animal1 WHERE address = '空';
BEGIN
  FOR animal_rec IN animal_cur LOOP
    DBMS_OUTPUT.PUT_LINE( 'id:' || animal_rec.id );
    DBMS_OUTPUT.PUT_LINE( 'name:' || animal_rec.name );
  END LOOP;
END;

上記例では、animal_curという名前のカーソルを宣言し、そのカーソルを用いてFORループを実行しています。ループ内では、カーソルからフェッチした各行(animal_rec)のidとnameを出力しています。

カーソルFORループには、FETCH文で変数に代入した値をLOOP文の外から参照できない以外は通常のカーソルとほとんど違いがないので、カーソル処理を行う際には便利とのこと。

副問合せを使用したカーソルFORループ

副問合せを使用する場合は、カーソルを宣言する必要はありません。
下記が基本的な構文になります。

基本的な構文(副問合せ使用)
FOR ループ索引名 IN (副問合せ) LOOP
  実行したい処理を記述
END LOOP;

普通のカーソルFORループとの違いは、宣言部でカーソルを宣言する必要が無いことです。
必要になるのは、ループ自体の結果セットを決定するSELECT文を指定することになります。

明示カーソル属性とは

明示カーソル属性とは、明示カーソルの現在の状態を示すための特性で4つあります。

  1. %ISOPEN
    カーソルがオープンされている場合はTRUEを戻します。オープンされていない場合はFALSEを戻します。
  2. %FOUND
    カーソルがオープンされてから最初のフェッチまでNULLを戻します。その後、直前のフェッチが行を戻した場合はTRUEを戻し、直前のフェッチが行を戻さなかった場合はFALSEを戻します。
  3. %NOTFOUND
    これは%FOUNDとは逆に機能し、最新のフェッチの場合はTRUEを返します。直前のフェッチが行を取得できなかった場合、つまり、結果セットの最後に達した場合や、まだフェッチが行われていない場合はFALSEを返します。
  4. %ROWCOUNT
    これは、カーソルがオープンされてからフェッチされた行の数を返します。

感想

まだまだ参考書知識で実務では使用したことがないので、研修終了後に実際使用してみて、よりわかりやすい実行例や気づきがあれば更新していきたいと思います。

参考

プロとしてのOracle PL/SQL入門 第3版
Oracle Database 10g PL/SQL基礎

https://segakuin.com/oracle/plsql/cursor.html
https://dolphinpg.net/program/oracle-pl-sql-cursorfor/
https://www.shift-the-oracle.com/plsql/cursor-loop.html

Discussion