e-learning、オラクル研修、LMS(学習管理システム)のiStudy

e-learning、オラクル研修、LMS(学習管理システム)のiStudy

第10回 「カーソルFORループ文」

2012.02.20

前回までのように、カーソルで、1行1行をフェッチし、最後の行まで同じ処理を繰り返すというパターンでは、より簡単な方法で記述することができます。カーソルFORループ文と言います。簡単なので、可能であればカーソルFORループ文を使うことをお勧めします。

では、さっそくカーソルFORループ文を解説します。前回のサンプルプログラムと、それをカーソルFORループ文で書き換えた場合を比較しましょう。それぞれ、(A)、(B)とします。

(A) 一般的な記述
1 DECLARE
2 CURSOR CUR_EMP IS
3 SELECT EMPNO, ENAME FROM EMP
4 WHERE DEPTNO = &部門番号;
5 REC CUR_EMP%ROWTYPE;
6 BEGIN
7 OPEN CUR_EMP;
8 LOOP
9 FETCH CUR_EMP INTO REC;
10 EXIT WHEN CUR_EMP%NOTFOUND;
11 DBMS_OUTPUT.PUT_LINE(REC.EMPNO || ' ' || REC.ENAME);
12 END LOOP;
13 CLOSE CUR_EMP;
14 END;

(B) カーソルFORループを使った記述
1 DECLARE
2 CURSOR CUR_EMP IS
3 SELECT EMPNO, ENAME FROM EMP
4 WHERE DEPTNO = &部門番号;
5 BEGIN
6 FOR REC IN CUR_EMP LOOP
7 DBMS_OUTPUT.PUT_LINE(REC.EMPNO || ' ' || REC.ENAME);
8 END LOOP;
9 END;

まず、カーソルFORループ文と言われている部分は、(B)の6~8行目です。構文として書くと、以下の通りです。

FOR レコード変数名 IN カーソル名 LOOP
レコード変数を使ったプログラム処理
END LOOP;

さて、この構文を使うと、さまざまな記述が不要になります。以下の内容です。

【不要な記述】
・レコード変数の宣言 (A)の5行目
・カーソルのオープン処理 (A)の7行目
・フェッチ処理 (A)の9行目
・ループの終了処理 (A)の10行目
・カーソルのクローズ処理 (A)の13行目

どうですか?とても多くの記述が不要になってますね。ですから、(B)のようにとても少ないステップ数でプログラムが書けるのです。なおカーソルFORループ文に使われているレコード変数((B)の6行目のREC )は宣言部で宣言されないことになりますが、それでもいいのです。そのかわり、そのレコード変数はカーソルFORループ文の中でのみ参照可能です。

上記の(B)をさらに簡単にできます。それは、カーソルFORループ文のカーソル名の代わりに括弧()で囲ったSELECT文を直接記述する方法です。

FOR レコード変数名 IN (SELECT・・・・) LOOP
レコード変数を使ったプログラム処理
END LOOP;

この方法だと、実行部でまったくカーソル名を参照していないので宣言部のカーソル宣言も不要です。宣言部でなにも宣言するものがないときは宣言部そのものも不要です。以下の(C)がそのような形に書き換えたものです。

(C) カーソル宣言しないカーソルFORループの記述
1 BEGIN
2 FOR REC IN (SELECT EMPNO, ENAME FROM EMP WHERE DEPTNO = &部門番号) LOOP
3 DBMS_OUTPUT.PUT_LINE(REC.EMPNO || ' ' || REC.ENAME);
4 END LOOP;
5 END;

(A)(B)(C)はまったく同じ処理を行いますが、(A)は14行の記述なのに、(C)はわずかに5行です。驚くほど簡単になっていますね。簡単だということは、プログラムも見やすいし、プログラムミスも防げるということです。

いかがですか?ぜひ、利用してください。

それでは今回はここまでです。次回、ご期待ください。

先頭へ戻る