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

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

第62回 「バルク・バインド(FETCH BULK COLLECT INTOの場合)」

2013.06.17

こんにちは。インストラクターの蓑島です。

前回は、SELECT INTO 文のバルク・バインド版ということで、SELECT BULK COLLECT INTO文 を解説しました。
今回は、明示カーソルにおけるFETCH INTO 文のバルク・バインド版ということで、FETCH  BULK COLLECT INTO 文を解説します。

FETCH BULK COLLECT INTO 文を使うと、結果セットのすべての行を一括でFETCHできます。
したがって、1行ずつFETCHするよりも、パフォーマンスが良くなります。

では、早速、普通のFETCH INTO 文の処理と、FETCH BULK COLLECT INTO 文の処理をそれぞれ実行して比較してみます。

今回も前回と同じく、TEST01表を使います。

SQL> DESC TEST01
 名前                                            NULL?                 型
 -------------------------------------- ----------- ----------------------------
 A                                                                           NUMBER
 B                                                                           VARCHAR2(10)

ご覧のように、A列、B列だけの単純な表です。
表の中のデータは、前回のように50万行ではなく、以下のように10行だけにしました。

SQL> SELECT * FROM TEST01 ORDER BY A;

         A       B
---------- ----------
         1      AA
         2      BB
         3      CC
         4      DD
         5      EE
         6      FF
         7      GG
         8      HH
         9      II
        10     JJ

10行が選択されました。

では、まずは普通のFETCH INTO 文を使った明示カーソル処理を行います。

画面表示を有効にして

SQL> SET SERVEROUTPUT ON

実行します。

SQL> DECLARE
  2    -- カーソルの宣言
  3    CURSOR  C1 IS SELECT * FROM TEST01 ORDER BY A;
  4    -- レコード型変数の宣言
  5    REC     C1%ROWTYPE;
  6  BEGIN
  7    OPEN C1;   -- カーソルオープン(結果セットの生成)
  8    LOOP       -- ループ処理
  9       FETCH C1 INTO REC;   -- 1行フェッチ
 10       EXIT WHEN C1%NOTFOUND;
 11       DBMS_OUTPUT.PUT_LINE(REC.B);  -- B列を画面表示
 12    END LOOP;
 13    CLOSE C1;  -- カーソルクローズ(結果セットの開放)
 14  END;
 15  /
AA
BB
CC
DD
EE
FF
GG
HH
II
JJ

PL/SQLプロシージャが正常に完了しました。

ごく一般的な、明示カーソル処理ですね。
B列の値が順番どおりに表示されました。(AA,BB,・・・)明示カーソル処理についての基本は、バックナンバー第7号~第9号をご覧ください。

では、次に、FETCH BULK COLLEC INTO文をつかった処理です。

SQL> DECLARE
  2        -- カーソルの宣言
  3    CURSOR  C1 IS SELECT * FROM TEST01 ORDER BY A;
  4        -- レコード型変数の配列の型を宣言
  5    TYPE RECTAB_TYPE IS TABLE OF C1%ROWTYPE INDEX BY BINARY_INTEGER;
  6        -- その型でレコード型の配列を宣言
  7    RECTAB     RECTAB_TYPE;
  8        -- 配列用の変数
  9    J          BINARY_INTEGER;
 10  BEGIN
 11    OPEN C1;   -- カーソルオープン(結果セットの生成)
 12    FETCH C1 BULK COLLECT INTO RECTAB;   -- 結果セット全体をバルクフェッチ
 13    CLOSE C1;  -- カーソルクローズ(結果セットの開放)
 14    -- 配列 RECTABの値を逆の順番で表示
 15    J := RECTAB.LAST;   -- 最初に最後の添え字取得(10番)
 16    LOOP  -- 配列を使ったループ処理
 17       DBMS_OUTPUT.PUT_LINE(RECTAB(J).B);   -- 画面表示
 18       EXIT WHEN J = RECTAB.FIRST;  -- 最初の添え字であればループを終了
 19       J := RECTAB.PRIOR(J);   -- 一つ前の添え字を取得
 20    END LOOP;
 21  END;
 22  /
JJ
II
HH
GG
FF
EE
DD
CC
BB
AA

PL/SQLプロシージャが正常に完了しました。

では、解説します。

まず、FETCH BULK COLLEC INTO 文では、一括で複数行を格納しますので、格納先の変数は、配列である必要があります。
そこで、配列を宣言します。(5行で、配列の型を宣言、7行でその型を使って変数宣言)

次に実行部で、カーソルをオープン(11行目)した後、結果セット全体を一括で、配列変数にフェッチしてます。(12行目)

結果セットはすべての行を取り出すと再利用できない無用の長物となりますので、速かにクローズ(13行目)します。

カーソルクローズにより、結果セットは解放されますが、配列は残ります。
配列は、結果セットと違って、添字により任意の場所にランダムにアクセスできますので、ここでは、逆の順番で配列の値を画面表示してみました。
(JJ→II→・・・BB→AA)

以上が上記の処理の解説です。

まとめますと、FETCH BULK COLLECT INTO文の構文は以下の通りです。

FETCH  カーソル名  BULK COLLECT INTO 配列変数 [ LIMIT  行数 ]

上記の構文の中で、[ LIMIT  行数 ]の部分はオプションですが、一回でバルクフェッチする行数を指定することができます。
これは、SELECT BULK COLLECT INTO 文にはない機能です。

次回は、このLIMIT句について解説します。
この機能を使えばメモリの使用量を抑えることができますので、状況によりパフォーマンス向上に役立つ場合があります。

なお、今回の処理の中で、配列の添字を逆の順番でたどっていますが、このような添字操作は、バックナンバー第14号にくわしく書いていますのでご参照ください。

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

先頭へ戻る