PL/SQL によるバルクインサート処理
バルクインサート処理 (BULK INSERT:FORALL 構文) は 1 回のコンテキストスイッチで大量のレコードを処理(バルク処理)することができる。
このコンテキストスイッチ(PL/SQL エンジンと SQL エンジンの間で発生する処理のやり取り)
の回数を減らすことによって大量データの処理時のレスポンスを向上することが可能になる。
このバルクインサート例ではバルクフェッチ(取り出し)とバルクインサートに
レコード型 の コレクション を
使用している。バルクインサートに対してレコード型を使用できるのは Oracle 9i 以降となる。
Oracle 8i 以前でのバルクインサート処理
Oracle 8i 以前ではレコード型によるバルクインサートには対応していない。
フィールド数が多いとやや面倒になるが、バルクインサート処理自体は Oracle 8i でも記述できるが、単一データ型によるコレクションを複数個用いることで実装することが可能。
バルクインサートに使う表定義
表定義は SQL 入門 のテーブル定義を流用して行なう。さらにインサート処理用に以下の作業を行なう。
CREATE TABLE RIVUS.USER_MASTER_COPY AS SELECT * FROM RIVUS.USER_MASTER WHERE 1=0;
ALTER TABLE RIVUS.USER_MASTER_COPY ADD PRIMARY KEY (USER_ID);
バルクインサートの例 (FOR ALL)
バルクフェッチ を行なった コレクション をバルクインサートする。
バルク処理の途中で発生したエラーは eBulkProcessNotComplete で例外処理し(※)継続処理する 。(SAVE EXCEPTIONS オプションによって終了しない)
(※) 例外処理部の実装は行なっていない。暗黙カーソル SQL%BULK_EXCEPTIONS 配列を使用することで例外の発生した要素番号とエラーコードが取得できる。
索引が不連続なコレクションに対するバルクインサート
FORALL 構文(FOR と ALL にスペースなし)を使用するには連続した索引をもつ コレクション型 であることが条件であったが Oracle 10g からコレクションの一部を DELETE した索引が不連続なコレクションでも索引を再構築せずに バルクインサートが可能になっている。
FORALL index IN INDICES OF collection ... / FORALL index IN VALUES OF collection ... 構文
INDICES OF*1 は索引部を VALUES OF はコンテンツ部を取り出すための述語となり、上のサンプル例のバルク処理部を書き換えて少しアレンジを加えると、以下のようになる。
関連事項