首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle 游標全解析:隱式/顯式游標、屬性、FOR 循環與 REF CURSOR 實戰

     編輯:Oracle 資料庫基礎

前言

游標是 PL/SQL 處理多行查詢結果的核心機制。本文系統講解隱式/顯式游標、游標屬性、FOR LOOP 簡化寫法、參數化游標、REF CURSOR 動態游標,並附完整代碼示例。

一、隱式游標(SQL 隱式游標)

DML (INSERT/UPDATE/DELETE) 和 SELECT INTO 單行查詢自動打開隱式游標,屬性前綴 SQL%:

屬性類型含義
SQL%FOUNDBOOLEAN最近 DML/SELECT INTO 影響/返回 ≥1 行
SQL%NOTFOUNDBOOLEANSQL%FOUND 邏輯反面
SQL%ROWCOUNTNUMBER最近 DML 影響行數 / SELECT INTO 返回行數(0/1)
SQL%ISOPENBOOLEAN隱式游標始終為 FALSE(執行即關閉)

示例:SQL%ROWCOUNT 判斷更新結果

BEGIN
  UPDATE emp SET sal = sal * 1.1 WHERE deptno = 20;
  IF SQL%ROWCOUNT = 0 THEN
    DBMS_OUTPUT.PUT_LINE('無符合條件記錄');
  ELSE
    DBMS_OUTPUT.PUT_LINE('更新 ' || SQL%ROWCOUNT || ' 行');
  END IF;
END;

二、顯式游標(聲明、打開、提取、關閉)

語法結構

DECLARE
  CURSOR c_emp (p_deptno NUMBER) IS  -- 參數化游標
    SELECT empno, ename, sal FROM emp WHERE deptno = p_deptno;
  v_empno emp.empno%TYPE;
  v_ename emp.ename%TYPE;
  v_sal   emp.sal%TYPE;
BEGIN
  OPEN c_emp(20);
  LOOP
    FETCH c_emp INTO v_empno, v_ename, v_sal;
    EXIT WHEN c_emp%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || v_ename || ' ' || v_sal);
  END LOOP;
  CLOSE c_emp;
END;

顯式游標屬性(前綴 游標名%)

屬性說明
%FOUND最近 FETCH 成功返回行
%NOTFOUND最近 FETCH 無數據
%ROWCOUNT已提取行數
%ISOPEN游標是否打開

三、游標 FOR 循環(隱式 OPEN/FETCH/CLOSE)

BEGIN
  FOR r IN (SELECT empno, ename, sal FROM emp WHERE deptno = 20) LOOP
    DBMS_OUTPUT.PUT_LINE(r.empno || ' ' || r.ename || ' ' || r.sal);
  END LOOP;
  -- 循環結束自動關閉,無需聲明變量
END;

參數化版本:

DECLARE
  CURSOR c_emp(p_deptno NUMBER) IS SELECT * FROM emp WHERE deptno = p_deptno;
BEGIN
  FOR r IN c_emp(30) LOOP
    -- 處理 r.*
  END LOOP;
END;

四、%TYPE 與 %ROWTYPE 錨定類型

  • v_sal emp.sal%TYPE:繼承列類型,DDL 變更自動適配。
  • r_emp emp%ROWTYPE:繼承整行結構,適用於 SELECT * INTO r_emp ... 或游標記錄變量。

五、REF CURSOR(動態游標/弱類型游標)

用於存儲過程返回結果集給客戶端(Java/.NET/報表工具)。

CREATE OR REPLACE PROCEDURE get_emp_by_dept(
  p_deptno IN NUMBER,
  p_rc     OUT SYS_REFCURSOR
) AS
BEGIN
  OPEN p_rc FOR SELECT empno, ename, sal FROM emp WHERE deptno = p_deptno;
END;

客戶端調用獲取 ResultSet/DataReader 遍歷。

六、最佳實踐清單

  1. 單行查詢用 SELECT INTO(隱式游標),多行用顯式游標或 FOR 循環。
  2. 優先用 FOR LOOP 減少樣板代碼,除非需精確控制 OPEN/FETCH/CLOSE 時機。
  3. 游標查詢盡量加 WHERE 過濾,避免全表掃描進內存。
  4. 大數據量分頁處理時,考慮 BULK COLLECT ... LIMIT 減少上下文切換。
  5. 動態 SQL 場景用 REF CURSOR 或 DBMS_SQL。

總結

掌握隱式/顯式游標屬性、FOR 循環簡化邏輯、%TYPE/%ROWTYPE 類型錨定、REF CURSOR 跨語言交互,即可覆蓋 95% PL/SQL 游標應用場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved