我們知道PL/SQL程序中運行SQL語句是存在開銷的
但是
請再看下圖
下面詳解這爺倆
㈠ 通過BULK COLLECT 加速查詢
⑴ BULK COLLECT 的用法
采用BULK COLLECT可以將查詢結果一次性地加載到collections中
可以在select into
注意在使用BULK COLLECT時
舉幾個簡單例子
① 在select into語句中使用bulk collect
[sql]
DECLARE
TYPE sallist IS TABLE OF employees
sals sallist;
BEGIN
SELECT salary BULK COLLECT INTO sals FROM employees where rownum<=
END;
/
② 在fetch into中使用bulk collect
[sql]
DECLARE
TYPE deptrectab IS TABLE OF departments%ROWTYPE;
dept_recs deptrectab;
CURSOR cur IS SELECT department_id
BEGIN
OPEN cur;
FETCH cur BULK COLLECT INTO dept_recs;
END;
/
③ 在returning into中使用bulk collect
[sql]
CREATE TABLE emp AS SELECT * FROM employees;
DECLARE
TYPE numlist IS TABLE OF employees
enums numlist;
TYPE namelist IS TABLE OF employees
names namelist;
BEGIN
DELETE emp WHERE department_id=
RETURNING employee_id
DBMS_OUTPUT
FOR i IN enums
LOOP
DBMS_OUTPUT
END LOOP;
END;
/
deleted
employee#
employee#
employee#
employee#
employee#
employee#
⑵ BULK COLLECT 對大數據DELETE UPDATE的優化
這裡舉DELETE就可以了
舉個案例
需要在一個
需求是在對數據庫其他應用影響最小的情況下
如果業務無法停止的話
根據ROWID分片
在業務無法停止的時候
一般可以控制在每一萬行以內提交一次
我在做大DML時
選擇業務低峰時做
代碼如下
[sql]
DECLARE
CURSOR mycursor IS SELECT rowid FROM t WHERE OO=XX ORDER BY rowid;
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
EXIT WHEN unt=
FORALL i IN v_rowid
DELETE t WHERE rowid=v_rowid(i)
COMMIT;
END LOOP;
CLOSE mycursor;
END;
/
⑶ 限制BULK COLLECT 提取的記錄數
語法
FETCH cursor BULK COLLECT INTO …[LIMIT rows];
其中
假設你需要查詢並處理
可是
這時
例子
[sql]
DECLARE
CURSOR allrows_cur IS SELECT * FROM employees;
TYPE employee_aat IS TABLE OF allrows_cur%ROWTYPE INDEX BY BINARY_INTEGER;
v_emp employee_aat;
BEGIN
OPEN allrows_cur;
LOOP
FETCH allrows_cur BULK FETCH INTO v_emp LIMIT
/*通過掃描集合對數據進行處理*/
FOR i IN
LOOP
upgrade_employee_status(v_emp(i)
END LOOP;
EXIT WHEN allrows_cur%NOTFOUND;
END LOOP;
CLOSE allrows_cur;
END;
/
⑷ 批量提取多列
需求
提取transportation表中的油耗小於
代碼如下
[sql]
DECLARE
TYPE vehtab IS TABLE OF transportation%ROWTYPE;
gas_quzzlers vehtab;
BEGIN
SELECT * BULK COLLECT INTO gas_quzzlers FROM transportation WHERE mileage <
…
⑸ 對批量操作使用RETURNING子句
有了returning子句後
例子請見BULK COLLECT 的用法的第三小點
㈡ 通過FORALL 加速DML
FORALL告訴PL/SQL引擎要先把一個或多個集合的所有成員都綁定到SQL語句中
From:http://tw.wingwit.com/Article/program/Oracle/201311/18706.html