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

Oracle PL/SQL 集合實戰:關聯陣列、游標 %ROWTYPE 與 PLS_INTEGER 效能

     編輯:Oracle 資料庫基礎

PL/SQL 集合三大類型

類型特徵索引適用場景
關聯陣列稀疏、無上限、僅 PL/SQL 可用BINARY_INTEGER / PLS_INTEGER / VARCHAR2暫存查詢結果、查找表、快取
巢狀表可持久化至資料表、支援多集合操作連續整數從 1 開始資料欄位型別、大量資料搬運
VARRAY固定上限、有序、儲存連續連續整數從 1 開始小型固定集合、物件屬性

關聯陣列宣告範例


-- 1. 純量型別陣列
TYPE arr_str IS TABLE OF VARCHAR2(5) INDEX BY BINARY_INTEGER;

-- 2. 記錄型別陣列(搭配游標 %ROWTYPE)
TYPE v_table1 IS TABLE OF cur1%ROWTYPE INDEX BY PLS_INTEGER;

關鍵型別差異:BINARY_INTEGER vs PLS_INTEGER

特性BINARY_INTEGERPLS_INTEGER
執行引擎Oracle 軟體模擬硬體原生(CPU 整數運算)
溢位行為自動轉 NUMBER 不報錯**溢位報錯**(-2^31 ~ 2^31-1)
效能較慢**快 2~3 倍**
建議相容舊代碼**新代碼首選**

**結論**:索引、迴圈計數器、整數運算**一律用 PLS_INTEGER**。

%ROWTYPE 與 %TYPE 實戰


DECLARE
  CURSOR cur1 IS SELECT empno, ename, sal FROM emp WHERE deptno = 10;
  -- 陣列元素型別直接綁定游標列定義
  TYPE emp_arr IS TABLE OF cur1%ROWTYPE INDEX BY PLS_INTEGER;
  v_emps emp_arr;
  v_idx  PLS_INTEGER := 0;
BEGIN
  FOR r IN cur1 LOOP
    v_idx := v_idx + 1;
    v_emps(v_idx) := r;  -- 整筆記錄賦值
  END LOOP;
  -- 陣列遍歷
  FOR i IN 1..v_idx LOOP
    DBMS_OUTPUT.PUT_LINE(v_emps(i).ename || ':' || v_emps(i).sal);
  END LOOP;
END;
/
  • %ROWTYPE:自動適應游標/表欄位變更,**免維護**。
  • 陣列索引從 1 起跳(或自訂),v_emps(v_idx) := r 整筆寫入。

進階:BULK COLLECT + FORALL 高效能批次處理


DECLARE
  TYPE id_arr IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
  v_ids id_arr;
BEGIN
  -- 一次性抓取至陣列,減少 Context Switch
  SELECT empno BULK COLLECT INTO v_ids FROM emp WHERE deptno = 20;

  -- 批次更新,單次 SQL 引擎往返
  FORALL i IN v_ids.FIRST..v_ids.LAST
    UPDATE emp SET sal = sal * 1.1 WHERE empno = v_ids(i);

  DBMS_OUTPUT.PUT_LINE('Updated ' || SQL%ROWCOUNT || ' rows');
END;
/

效能提升:10,000 筆資料,FOR LOOP ~ 8 秒 → BULK COLLECT + FORALL ~ 0.3 秒。

常見陷阱與避坑

  1. 未初始化直接賦值:關聯陣列宣告後即可直接 arr(1) := 'a',無需 NEW 或 EXTEND(巢狀表/VARRAY 需)。
  2. 索引型別不匹配:INDEX BY PLS_INTEGER 卻用 VARCHAR2 索引 → 編譯錯誤。
  3. 溢位未處理:PLS_INTEGER 迴圈超過 21 億報錯,大量資料用 NUMBER 索引或分批。
  4. FORALL **不支援** WHERE CURRENT OF、RETURNING(11g+ 支援 RETURNING BULK COLLECT)。

結語

掌握 關聯陣列 + %ROWTYPE + PLS_INTEGER 黃金組合,配合 BULK COLLECT / FORALL,是 PL/SQL 高效能批次處理的核心技能。記住:**索引用 PLS_INTEGER、型別用 %ROWTYPE、批次用 FORALL**,即可寫出既簡潔又極速的資料處理邏輯。

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