佔用較少undo,資源(獨佔鎖,undo)快速釋放,執行時間長web
在線大批量插入,更新,刪除數據sql
無論是顯示遊標仍是隱式遊標,均可以經過BULK COLLECT在數據庫的單次交互中獲取多行數據。BULKCOLLECT相對Cursor Loop方式減小了PL/SQL引擎和SQL引擎之間的切換次數,所以也減小了提取數據時的額外開銷。
數據庫
這種方法會減小對PGA的消耗,避免換頁產生app
FORALL告訴PL/SQL引擎要先把一個或多個集合的全部成員都綁定到SQL語句中,而後再把語句發送給SQL引擎, 若是for ..loop 循環,那麼會發送n(循環的次數)次,而用Forall,一次行所有發送過去。
oop
declare TYPE ARRAY IS TABLE OF big_table%ROWTYPE; l_data ARRAY; CURSOR c IS SELECT * FROM big_table; BEGIN OPEN c; LOOP FETCH c BULK COLLECT INTO l_data LIMIT 5000; FORALL i IN 1 .. l_data.COUNT INSERT /*+append*/ INTO big_table VALUES l_data (i); commit; EXIT WHEN c%NOTFOUND; END LOOP; CLOSE c;
DECLARE CURSOR mycursor IS SELECT rowid FROM t WHERE OO = XX; TYPE rowid_table_type IS TABLE OF rowid index by pls_integer; v_rowid rowid_table_type; BEGIN OPEN mycursor; LOOP FETCH mycursor BULK COLLECT INTO v_rowid LIMIT 5000; EXIT WHEN v_rowid.count = 0; FORALL i IN v_rowid.FIRST .. v_rowid.LAST DELETE t WHERE rowid = v_rowid(i); COMMIT; END LOOP; CLOSE mycursor; END;
DECLARE CURSOR mycursor IS SELECT t_pk FROM t WHERE OO = XX; TYPE num_tab_t IS TABLE OF NUMBER(38); pk_tab NUM_TAB_T; BEGIN OPEN mycursor; LOOP FETCH mycursor BULK COLLECT INTO pk_tab LIMIT 5000; EXIT WHEN pk_tab.count = 0; FORALL i IN pk_tab.FIRST .. v_rowid.LAST UPDATE t SET name = name || ’bulk’ WHERE t_pk = pk_tab(i); COMMIT; END LOOP; CLOSE mycursor; END;