連載
» 2018年11月19日 05時00分 公開

PL/SQLでカーソルを使う(基本編)超入門「PL/SQL」(6)(2/3 ページ)

[小笠原宏幸,@IT]

カーソル処理の記述方法

 先ほどの説明からも分かる通り、カーソル処理の記述はこれまでの連載内容と比べると複雑です。まずは、図5でカーソルを使う際に必要な記述の全体像を確認してください。

図5 カーソル処理の記述概要

 それでは、図5をベースに各項目の記述方法を解説します。

(1)カーソルの定義

 実行したいSELECT文に対してカーソル名を定義します。カーソル名は変数と同様の「命名規則」に従います。このとき「SQL」という名前は指定できません。

CURSOR <カーソル名> IS <問い合わせ文> ;
カーソルを定義する書式

(2)変数の定義

 実行部でカーソルの結果セットを1行ずつ変数に代入します。変数はカーソルの結果セットの列ごとに定義するのではなく、通常は「<カーソル名>%ROWTYPE」と定義します。こうすることで、結果セットと同じ行構造の変数を用意できます。

<変数名> <カーソル名>%ROWTYPE ;
変数を定義する書式

(3)カーソルのオープン

 カーソルに対応付けられたSELECT文を実行し、結果セットを識別します。結果セットはオープンした時点のデータを保持します。

OPEN <カーソル名> ;
カーソルをオープンする書式

(4)結果セットから変数へ代入

 カーソルの結果セットから1行を取り出し、(2)で定義した変数に代入します。

FETCH <カーソル名> INTO <変数名> ;
1行を取り出し、変数に代入する書式

 FETCH INTO文を使用する際は、次に挙げる挙動に注意してください。

  • FETCH INTO文は1行のみを取り出すため、LOOP文を併用して複数行を取り出します。
  • 結果セットは、オープン直後は1行目、次は2行目……というように上から順番に取り出されます。

(5)LOOP処理の終了

 LOOP処理によって結果セットから複数行を取り出した後、このLOOP処理を終了する条件が必要です。終了条件の指定方法は幾つかありますが、今回はEXIT WHEN文を使用した方法を解説します。

EXIT WHEN <終了条件> ;
LOOP処理を終了する書式

 終了条件にはWHERE句と同様の条件式を指定できる他、後ほど説明する「カーソル属性」を指定できます。カーソル属性を使用すると、例えば「結果セットの全行を取り出して、取り出す行がなくなったらLOOP処理を終了する」というような指定が可能です。

(6)カーソルのクローズ

 結果セットが確保していたメモリ領域を解放します。なお、クローズ処理の明示的な指定を省略できますが、その場合、PL/SQLブロックが終了するまでは結果セットのメモリ領域を確保し続けます。メモリを有効活用するためにも、一連の処理が終了したらクローズ処理を指定するようにしましょう。

CLOSE <カーソル名> ;
カーソルをクローズする書式

サンプルプログラムでカーソルを使う

 それでは、カーソルの記述方法をサンプルプログラムで確認しましょう。

SQL> DECLARE
 2    CURSOR dept_cur IS SELECT * FROM dept;
 3    dept_rec dept_cur%ROWTYPE;
 4  BEGIN
 5    OPEN dept_cur;
 6      LOOP
 7        FETCH dept_cur INTO dept_rec;
 8        EXIT WHEN dept_cur%NOTFOUND;
 9          DBMS_OUTPUT.PUT_LINE(dept_rec.deptno||' : '||dept_rec.dname||' : '||dept_rec.loc);
10      END LOOP;
11    CLOSE dept_cur;
12  END;
13  /
10 : ACCOUNTING : NEW YORK
20 : RESEARCH : DALLAS
30 : SALES : CHICAGO
40 : OPERATIONS : BOSTON
カーソルを使うサンプルプログラム

 初めに宣言部で「SELECT * FROM dept;」というSELECT文に対して、DEPT_CURという名前でカーソル名を定義しています。併せて、カーソルの結果セットの行を代入するため、変数DEPT_RECを「dept_cur%ROWTYPE」で定義しています。

 次に実行部でOPEN文を使用し、カーソルDEPT_CURに対応付けたSELECT文を実行しています。これによって結果セットが識別されます。その後、FETCH INTO文を使用して、結果セットの1行目を変数DEPT_RECに代入しています。そして、変数DEPT_RECの各フィールドに代入されている値をDBMS_OUTPUT.PUT_LINEで出力しています。

 この「変数への代入→値の出力」という一連の処理を、結果セットの2行目以降でも繰り返し行うため、LOOP文を併用しています。また、LOOP〜END LOOP間には、LOOP処理を終了するためにEXIT WHEN文を指定しています。「dept_cur%NOTFOUND」という条件を指定しているため、カーソルDEPT_CURの結果セットが全行取り出され、取り出す行がなくなったらLOOP処理を終了します(カーソル属性の%NOTFOUNDは次に説明します)。

 最後にCLOSE文を指定し、カーソルをクローズしています。これで結果セットが確保していたメモリ領域を解放します。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。