| 屬性 | 意義 |
| %ISOPEN | BOOLEAN,游標是否開啟 |
| %FOUND | BOOLEAN,最近 FETCH 是否取到資料 |
| %NOTFOUND | BOOLEAN,最近 FETCH 未取到資料 |
| %ROWCOUNT | NUMBER,累計 FETCH 筆數 |
基礎範例:手動控制迴圈
SET SERVEROUTPUT ON
DECLARE
v_empno VARCHAR2(20);
v_empzc VARCHAR2(20);
CURSOR c_emp (p_comno NUMBER) IS
SELECT emp_no, emp_zc FROM cus_emp_basic WHERE com_no = p_comno;
BEGIN
IF NOT c_emp%ISOPEN THEN OPEN c_emp(627); END IF;
FETCH c_emp INTO v_empno, v_empzc;
WHILE c_emp%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(v_empno || ',' || v_empzc);
EXIT WHEN c_emp%ROWCOUNT = 2; -- 僅示範前 2 筆
FETCH c_emp INTO v_empno, v_empzc;
END LOOP;
CLOSE c_emp;
END;
/
進階範例:搭配 RECORD 型別
SET SERVEROUTPUT ON
DECLARE
TYPE r_emp IS RECORD (
empno cus_emp_basic.emp_no%TYPE,
empzc cus_emp_basic.emp_zc%TYPE
);
v_rec r_emp;
CURSOR c_emp (p_comno NUMBER) IS
SELECT emp_no, emp_zc FROM cus_emp_basic WHERE com_no = p_comno;
BEGIN
IF NOT c_emp%ISOPEN THEN OPEN c_emp(627); END IF;
LOOP
FETCH c_emp INTO v_rec;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('員工編號:' || v_rec.empno || ', 地址:' || v_rec.empzc);
END LOOP;
CLOSE c_emp;
END;
/
最佳寫法:CURSOR FOR LOOP(自動開啟/擷取/關閉)
SET SERVEROUTPUT ON
DECLARE
CURSOR c_emp (p_comno NUMBER) IS
SELECT emp_no, emp_zc FROM cus_emp_basic WHERE com_no = p_comno;
BEGIN
FOR r IN c_emp(627) LOOP
DBMS_OUTPUT.PUT_LINE('員工編號:' || r.emp_no || ', 地址:' || r.emp_zc);
END LOOP;
-- 迴圈結束自動 CLOSE,不可在迴圈內再用 OPEN/FETCH/CLOSE
END;
/
參數化游標與變數作用域
- 參數僅在
OPEN 或 FOR 時綁定,游標本體可重複開啟不同參數值。
- 游標宣告於
DECLARE 區塊,作用域限於該區塊;套件規格中宣告則為公共游標。
REF CURSOR:動態游標與跨層傳遞
TYPE t_refcur IS REF CURSOR;
v_cur t_refcur;
OPEN v_cur FOR SELECT * FROM employees WHERE department_id = :dept_id;
-- 可傳給 Java/.NET 客戶端、或另一 PL/SQL 程式處理
效能與最佳實踐
- 優先使用
CURSOR FOR LOOP,程式碼最簡潔、不易漏關閉。
- 大量資料處理改用
BULK COLLECT ... LIMIT 1000 + FORALL,減少 Context Switch。
- 游標查詢務必加上適當 WHERE 條件,避免全表掃描後再篩選。
- 長時間運行的游標考慮加上
FOR UPDATE SKIP LOCKED 避免阻塞。
- 例外處理區塊務必
CLOSE 游標,防止游標洩漏導致 ORA-01000。
常見錯誤與排查
| 錯誤 | 原因 | 修正 |
| ORA-01001 | 游標已關閉又 FETCH | 檢查邏輯流程,確保關閉前不再 FETCH |
| ORA-01000 | 開啟游標超過 open_cursors | 確保所有路徑都 CLOSE;調大參數 |
| ORA-06511 | 游標未開啟就 FETCH/CLOSE | 加上 %ISOPEN 判斷或重構邏輯 |
游標是 PL/SQL 處理集合資料的核心機制,掌握其生命週期與屬性,是編寫健壯存儲過程的必修課。
- 上一篇文章: Solaris 平台 Oracle 基礎操作指令速查
- 下一篇文章: Oracle 與 SQL Server 語法差異對照與移植指南
Copyright ©
程式碼之家 All Rights Reserved