先輩に「ここはBulk使うといいよ」と言われ、
色々調べてみたのでメモ。
お手軽に書けるわりに速くなることが多いみたい。
Bulk Insert
PL/SQL実行部
OPEN "カーソル名";
LOOP
FETCH "カーソル名" BULK COLLECT INTO "配列名" LIMIT 1000;
EXIT WHEN "配列名".count = 0;
FORALL I IN 1.."配列名".count
insert into "テーブル名" values "配列名"(I);
END LOOP;
CLOSE "カーソル名";
解説
2段のループになっています。
1つめは、2行目のLOOP。
FETCH - LIMIT
で指定した行(ここでは1000行)ごとに区切って
テーブル変数の配列に入れています。
2つめは、FORALLの部分。
FORALL I IN 1.."配列名".count
insert into "テーブル名" values "配列名"(I);
ここをふつーのFOR文で書くと
FOR I IN 1.."配列名".count LOOP
insert into "テーブル名" values "配列名"(I);
END LOOP
になります。
これでも動くのですが、
insertはSQLエンジンが実行し、
LOOP部分はPL/SQLエンジンが制御するため、
LOOP回数分オーバーヘッドが生じて遅くなるのだとか。
LIMITの数多くすればオーバーヘッドは減るけど
メモリなどは多く食うようになってしまうため要チューニング。
あと、カーソル、テーブル定義配列、その型は
宣言部で宣言しておく必要があります。
PL/SQL宣言部
CURSOR "カーソル名" IS (
select hogehoge from tableA --ふつーのSelect文
);
TYPE type1 IS TABLE OF "カーソル名"%ROWTYPE index by binary_integer;
"配列名" type1;
カーソルのカラム定義はもちろん
INSERT先と合わせる必要あります。
正直、調べれば調べるほど分からなくなり、
PL/SQLの基本が分かってないと痛感。
今は↑のようなおまじないがある、と理解しておく。
参考サイト
このシリーズすごく勉強になります。
http://www.istudy.ne.jp/training/serial/plsql/063.html