-- 精確暫停 2.5 秒
DBMS_LOCK.SLEEP(2.5);
DECLARE
v_delay CONSTANT PLS_INTEGER := 100; -- 1 秒 (單位:百毫秒)
v_start PLS_INTEGER;
v_end PLS_INTEGER;
BEGIN
v_start := DBMS_UTILITY.GET_TIME; -- 百毫秒
LOOP
v_end := DBMS_UTILITY.GET_TIME;
EXIT WHEN (v_end - v_start) >= v_delay;
-- 可放簡單運算避免優化器移除迴圈
NULL;
END LOOP;
-- 執行後續操作
INSERT INTO log_table VALUES ('Delayed action executed');
END;
| 場景 | 建議 | 理由 |
|---|---|---|
| PL/SQL → PL/SQL (同資料庫) | 集合 + BULK COLLECT | 單次 Context Switch 取回所有資料,避免逐行 Fetch 開銷;支援 `FORALL` 批次 DML。 |
| PL/SQL → 外部宿主 (Java, C#, SQL*Plus, Pro*C) | SYS_REFCURSOR (遊標變數) | 所有宿主語言驅動程式均支援遊標提取;集合型別跨語言對應複雜 (Oracle Types、SQLJ、UDT 映射)。 |
-- 批次提取 1000 列
FETCH cur BULK COLLECT INTO v_array LIMIT 1000;
-- 批次寫入
FORALL i IN INDICES OF v_array
INSERT INTO target_table VALUES v_array(i);
CREATE OR REPLACE PACKAGE pkg_cache AS
TYPE t_dept IS TABLE OF dept%ROWTYPE INDEX BY PLS_INTEGER;
g_depts t_dept;
PROCEDURE load_depts;
FUNCTION get_dept(p_deptno NUMBER) RETURN dept%ROWTYPE;
END;
/
CREATE OR REPLACE PACKAGE BODY pkg_cache AS
PROCEDURE load_depts IS
BEGIN
SELECT * BULK COLLECT INTO g_depts FROM dept;
END;
FUNCTION get_dept(p_deptno NUMBER) RETURN dept%ROWTYPE IS
BEGIN
RETURN g_depts(p_deptno); -- 直接記憶體存取,零 SQL 開銷
END;
END;
/
-- 應用啟動時呼叫 pkg_cache.load_depts
掌握 管道函數解鎖平行查詢、DBMS_LOCK/UTILITY 精確控制流、依呼叫端選擇集合或遊標、BULK COLLECT/FORALL 批次化、熱點靜態資料 PGA 快取,能將 PL/SQL 程式效能提升數個數量級,是高階 PL/SQL 開發者必備技能組合。