游標是指向查詢結果集的指針,讓程式能逐行處理 SELECT 返回的數據。分類:
CURSOR 游標名(參數列表) [RETURN 返回類型] IS
SELECT 語句;
%ROWTYPE 記錄型變量);SET SERVEROUTPUT ON
DECLARE
CURSOR emp_cur (p_deptid IN NUMBER) IS
SELECT * FROM employees WHERE department_id = p_deptid;
l_emp employees%ROWTYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE('Getting employees from department 30');
OPEN emp_cur(30);
LOOP
FETCH emp_cur INTO l_emp;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Employee id ' || l_emp.employee_id || ' is ' || l_emp.first_name || ' ' || l_emp.last_name);
END LOOP;
CLOSE emp_cur;
DBMS_OUTPUT.PUT_LINE('Getting employees from department 90');
OPEN emp_cur(90);
LOOP
FETCH emp_cur INTO l_emp;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Employee id ' || l_emp.employee_id || ' is ' || l_emp.first_name || ' ' || l_emp.last_name);
END LOOP;
CLOSE emp_cur;
END;
/
| 屬性 | 含義 |
|---|---|
%FOUND | 最近 FETCH 成功返回行 |
%NOTFOUND | 最近 FETCH 無數據 |
%ROWCOUNT | 已提取行數 |
%ISOPEN | 游標是否打開 |
TYPE ref_cur_t IS REF CURSOR RETURN employees%ROWTYPE;
PROCEDURE get_emps(p_deptid IN NUMBER, p_rc OUT ref_cur_t) IS
BEGIN
OPEN p_rc FOR SELECT * FROM employees WHERE department_id = p_deptid;
END;
優勢:解耦查詢邏輯與調用端,支援動態 WHERE 子句、跨會話/進程傳遞結果集、Java/.NET 等中間層直接消費。
EXIT WHEN cursor%NOTFOUND,避免無限循環;CLOSE 游標,防止游標洩漏;BULK COLLECT ... LIMIT 批量獲取,減少上下文切換;EXECUTE IMMEDIATE。