PL/SQL によるバルクフェッチ処理

PL/SQL の カーソル処理 には 1レコード単位にレコードを取り出す方式 だけではなく 複数のレコードを1回の処理で行うバルク処理がある。

バルク処理は1回の IO で大量のレコードを SELECT してそれを一度に FETCH 処理するために バッチ処理などメモリ資源を十分に確保できる状態では非常に効率よく実行することができる。

バルクフェッチ(取り出し)にはレコード型の コレクション型を使用するとコーディング量が減りメンテナンスも容易になる。 単一データの配列を複数使用する方法もあるが Oracle 9i からはレコード全体の INSERTUPDATE がサポートされているのでレコード型によるコレクション型を使用するほうが都合良いだろう。

バルクフェッチの例 (FETCH 〜 BULK COLLECT)

カーソル定義レコード型のコレクションによるバルクフェッチの例

CREATE OR REPLACE PROCEDURE RIVUS.BULK_FETCH
IS
  BULK_SIZE CONSTANT PLS_INTEGER := 4;  -- コンスタントでなくても良い
 
  CURSOR cIDName IS
    SELECT USER_ID, USER_NAME
      FROM USER_MASTER
    ORDER BY USER_ID DESC;
  TYPE tIDNAMES IS TABLE OF cIDName%ROWTYPE INDEX BY BINARY_INTEGER;
  --  ↑ カーソル定義によるレコード型のコレクション(結合配列)
 
  vIDName tIDNAMES;
BEGIN
  OPEN cIDName;
  LOOP
    FETCH cIDName BULK COLLECT INTO vIDName LIMIT BULK_SIZE;
    --   [バルク処理 ↑]  [代入先変数名 ↑]    [↑ 一度の最大フェッチ数(省略時は全て)]
    DBMS_OUTPUT.PUT_LINE('フェッチ数:' || vIDName.COUNT);
    EXIT WHEN vIDName.COUNT = 0;
    FOR i in 1 .. vIDName.COUNT
    LOOP
      DBMS_OUTPUT.PUT_LINE(vIDName(i).USER_ID || ':' || vIDName(i).USER_NAME);
    END LOOP;
  END LOOP;
  DBMS_OUTPUT.PUT_LINE('合計フェッチ数:' || cIDName%ROWCOUNT);
  CLOSE cIDName;
END;
/
-- 実行例
SQL> call bulk_fetch();
フェッチ数:4
0020:小泉 純一
0019:林 喜朗
0018:少渕 恵三
0017:橋本 太郎
フェッチ数:1
0001:鳩山 一代
合計フェッチ数:5

表定義は SQL 入門 のテーブル定義を流用して行なう。

 


関連事項

日本オラクル
■ 日本オラクル 株式会社
■ オラクルマスター資格 (オラクルマスターとは
■ Oracle Web セミナー