PL/SQLの勉強9 データを複数件取得する(カーソルの超基本)

2022-10-20

前回はデータを1件だけ取得したい時の
書き方を覚えました。

select … into … を使えば出来ましたね!

どこかのテーブルに入った「固定値」を
変数に持ちたい時に便利でしたね。

今回は「データを複数件取るための方法」
を勉強しようと思います。

ただし、カーソルには色々あるので…
今回は超基本をやろうと思います!

まずはサンプルのデータを用意

前回と同じく…

そんなのいらないよ!
と言う方は、次に行ってくださいw

こんな感じのデータを用意しますよ。

ID名前
1太郎
2花子
3光宙

以下のDDL・DMLを全部コピーして
Oracle Live SQLに貼り付け・実行すれば
自分で試すためのデータは用意できますよ♪

create table COMMON_MST
(
  ID   number
 ,NAME varchar2(4000)
 ,constraint PK_COMMON_MST primary key (ID)
)
;

insert into COMMON_MST values (1, '太郎');
insert into COMMON_MST values (2, '花子');
insert into COMMON_MST values (3, '光宙');

commit;

試しにちゃんとデータが入っているか
確認してみましょう。

select
*
from COMMON_MST
;

大丈夫そうですね!
これでデータの準備はOKです。

「カーソル」という考え方

テーブルからデータを「複数件」取る
と言っても、一気に取るわけではありません。

1行ずつ、1行ずつ…ってやていくんです!

1行ずつ…

この行の処理が終わったら
次の行…

この行の処理が終わったら
3行目へ…と。

例えばPCでは「マウス」を使いますよね。
マウスを動かすと矢印が動きます。
この矢印を「カーソル」と呼びますよね!

つまりカーソルとは、矢印のことです。
「今、この行をやってるよ〜」ということです。

1行ずつやっているので
「次の行に行くよ〜」というのもあります。
これをfetch(フェッチ)すると言います。

それでは実際にどう書くのか
見ていきましょう!

カーソルの書き方

超基本

まずは超基本的な書き方です。
こんな感じに書きますよ。

declare
  -- カーソルを定義
  cursor cur_common is
    select
      NAME
    from COMMON_MST
  ;
  -- データを保持するための変数を用意
  v_name  COMMON_MST.NAME%type;
begin
  -- カーソルをオープンする
  open cur_common;
  
  loop
    -- 1行ずつ処理(フェッチ)して、取得したデータを変数に持ち替える
    fetch cur_common into v_name;
    -- フェッチしてデータがなかったらloopを修了する
    exit when cur_common%notfound;
    -- 何らかの処理をする(今回は出力だけ)
    dbms_output.put_line(v_name);
  end loop;
  
  -- 最後にカーソルを閉じる
  close cur_common;
  
exception
  when others then
    dbms_output.put_line(SQLERRM);
end;

何やってるのか?を
全部コメント書いてみましたw

お作法として、こんな感じです。

3行目…まずはカーソルを定義しましょう。
どのテーブルからどんな情報を取得したいのか…?

9行目…そしてそれを1行ずつ受け取る変数も用意します。

12行目…カーソルを使うときは、最初にOPENします。
24行目…カーソルを使い終わったらCLOSEします。

LOOPでグルグル回します。
その中で…

16行目…1件ずつ、FETCHしていきます。

18行目…グルグル回していくと、そのうちデータが無くなります。
データが無くなったら、LOOPを終わりましょう。
このEXITがないと、永遠にLOOPが終わりません。。。

複数カラムを扱いたいときは

さっきはNAMEしかデータを取ってないですが
IDも一緒に取るとしたら…
こんな感じに書けますよね!

declare
  -- カーソルを定義
  cursor cur_common is
    select
      ID
     ,NAME
    from COMMON_MST
  ;
  -- データを保持するための変数を用意
  v_id    COMMON_MST.ID%type;
  v_name  COMMON_MST.NAME%type;
begin
  -- カーソルをオープンする
  open cur_common;
  
  loop
    -- 1行ずつ処理(フェッチ)して、取得したデータを変数に持ち替える
    fetch cur_common into v_id,v_name;
    -- フェッチしてデータがなかったらloopを修了する
    exit when cur_common%notfound;
    -- 何らかの処理をする(今回は出力だけ)
    dbms_output.put_line(v_id || ' : ' || v_name);
  end loop;
  
  -- 最後にカーソルを閉じる
  close cur_common;
  
exception
  when others then
    dbms_output.put_line(SQLERRM);
end;

IDを出すために
あちこちに変数「v_id」があります。

テーブルのデータ全部取得する場合は

COMMON_MSTというテーブルには
IDとNAMEしかカラムが無いので、
こんな感じにも書けますよね!

declare
  -- カーソルを定義
  cursor cur_common is
    select
      ID
     ,NAME
    from COMMON_MST
  ;
  -- データを保持するための変数を用意
  tbl_common_mst  COMMON_MST%rowtype;
begin
  -- カーソルをオープンする
  open cur_common;
  
  loop
    -- 1行ずつ処理(フェッチ)して、取得したデータを変数に持ち替える
    fetch cur_common into tbl_common_mst;
    -- フェッチしてデータがなかったらloopを修了する
    exit when cur_common%notfound;
    -- 何らかの処理をする(今回は出力だけ)
    dbms_output.put_line(tbl_common_mst.ID || ' : ' || tbl_common_mst.NAME);
  end loop;
  
  -- 最後にカーソルを閉じる
  close cur_common;
  
exception
  when others then
    dbms_output.put_line(SQLERRM);
end;

3つの違い、こちらを見れば
スッキリ分かると思いますので
一度見てみて下さいね♪

以上ですw

カーソルの超基本について
やっていきました。

いかがでしたか?

カーソルは、PL/SQLの真骨頂って
勝手に思ってますw

ぜひ読んで・やってみて・覚えてほしいなって思います!

PL/SQL

Posted by kiri