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

Oracle DML 隱式游標屬性詳解:SQL%FOUND/ROWCOUNT/ISOPEN 實戰應用

     編輯:Oracle 資料庫基礎

前言

每次執行 DML (INSERT/UPDATE/DELETE) 或 SELECT INTO 時,Oracle 自動打開隱式游標,通過 SQL% 前綴屬性即可獲取執行結果。本文詳細講解四大屬性語義、取值時機、典型應用場景與常見誤區。

四大隱式游標屬性

屬性類型含義取值示例
SQL%FOUNDBOOLEAN最近 DML/SELECT INTO 影響或返回 ≥1 行UPDATE 影響 3 行 → TRUE
SQL%NOTFOUNDBOOLEANSQL%FOUND 邏輯非DELETE 0 行 → TRUE
SQL%ROWCOUNTNUMBER最近 DML 影響行數 / SELECT INTO 返回行數 (0 或 1)INSERT 1 行 → 1
SQL%ISOPENBOOLEAN隱式游標始終為 FALSE (執行即自動關閉)永遠 FALSE

屬性值生命週期

  1. 執行前:SQL%FOUND/ NOTFOUND = NULL,SQL%ROWCOUNT = NULL。
  2. 執行後:立即更新,直到下一條 DML/SELECT INTO 執行前保持不變。
  3. 異常時:若 SELECT INTO 返回 0 行 → 拋出 NO_DATA_FOUND,屬性仍更新 (ROWCOUNT=0, NOTFOUND=TRUE)。

典型應用場景

1. 判斷更新是否生效


BEGIN
  UPDATE emp SET sal = sal * 1.1 WHERE deptno = 99;  -- 不存在的部門
  IF SQL%ROWCOUNT = 0 THEN
    DBMS_OUTPUT.PUT_LINE('無記錄更新,請檢查條件');
  ELSE
    DBMS_OUTPUT.PUT_LINE('成功更新 ' || SQL%ROWCOUNT || ' 行');
  END IF;
END;

2. 批量處理中控制提交頻率


DECLARE
  v_cnt NUMBER := 0;
BEGIN
  FOR r IN (SELECT * FROM big_table WHERE process_flag = 'N') LOOP
    UPDATE big_table SET process_flag = 'Y', process_time = SYSDATE WHERE id = r.id;
    v_cnt := v_cnt + SQL%ROWCOUNT;
    IF MOD(v_cnt, 1000) = 0 THEN
      COMMIT;  -- 每 1000 行提交一次
    END IF;
  END LOOP;
  COMMIT;
END;

3. SELECT INTO 異常處理替代方案


BEGIN
  SELECT sal INTO v_sal FROM emp WHERE empno = 9999;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    -- 也可用 SQL%NOTFOUND 判斷,但異常塊更清晰
    v_sal := 0;
END;

-- 或無異常寫法 (需確保唯一)
DECLARE
  v_cnt NUMBER;
BEGIN
  SELECT COUNT(*) INTO v_cnt FROM emp WHERE empno = 9999;
  IF v_cnt = 1 THEN
    SELECT sal INTO v_sal FROM emp WHERE empno = 9999;
  ELSE
    v_sal := 0;
  END IF;
END;

常見誤區與避坑

誤區正確理解
SQL%ROWCOUNT 可用於 SELECT 多行查詢隱式游標僅支持 SELECT INTO (單行);多行查詢需顯式游標或 BULK COLLECT
SQL%FOUND 在 IF 中直接用需注意 NULL執行前為 NULL,建議先執行 DML 再判斷,或用 SQL%ROWCOUNT > 0
隱式游標可重用每條 DML/SELECT INTO 都會重置屬性,不可跨語句引用上一條結果
SQL%ISOPEN 有實際用途永遠 FALSE,無實際參考價值

事務控制語句 (TCL) 速查

  • COMMIT:永久保存變更,釋放鎖。
  • ROLLBACK:撤銷變更,釋放鎖。
  • SAVEPOINT name:設置保存點,支持部分回滾 ROLLBACK TO name。
  • SET TRANSACTION READ ONLY / ISOLATION LEVEL SERIALIZABLE:設置事務特性。

總結

隱式游標屬性是 PL/SQL 控制流程的「儀表盤」。牢記 SQL%ROWCOUNT 為核心計數器,SQL%FOUND/NOTFOUND 為布爾判斷,SQL%ISOPEN 無用。在批量 DML、條件邏輯、異常處理中靈活運用,能編寫出健壯、高效的過程代碼。

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