PL/SQL 變數類型體系
- 標量類型:數值、字元、日期、布林
- 參考類型:REF CURSOR、物件參考
- 集合類型(複合類型):關聯陣列、嵌套表、VARRAY
三大集合類型對比
| 特性 | 關聯陣列 | 嵌套表 | VARRAY |
| 語法關鍵字 | INDEX BY BINARY_INTEGER | 無 INDEX BY | VARRAY(size) |
| 下標類型 | 整數(負數可) | 正整數(1起) | 正整數(1起,固定上限) |
| 儲存位置 | 僅記憶體(PGA) | 可持久化至資料庫欄位 | 可持久化至資料庫欄位 |
| DML 操作 | 不支援 | 支援(需初始化) | 支援(需初始化) |
| 擴展方式 | 自動擴展 | EXTEND 方法 | EXTEND 方法(不超上限) |
| 稀疏性 | 天然稀疏 | 稠密(可刪除中間元素變稀疏) | 稠密 |
| 適用場景 | 暫存查詢結果、快取、查找表 | 資料庫欄位、需持久化集合 | 固定大小集合、順序重要 |
關聯陣列實戰
宣告與使用
DECLARE
TYPE emp_aa_type IS TABLE OF emp%ROWTYPE INDEX BY BINARY_INTEGER;
v_emp emp_aa_type;
v_num NUMBER := 0;
CURSOR cur_emp IS SELECT * FROM emp;
BEGIN
-- 填充
FOR v_e IN cur_emp LOOP
v_num := v_num + 1;
SELECT * INTO v_emp(v_num) FROM emp WHERE ename = v_e.ename;
END LOOP;
-- 遍歷(稀疏安全)
FOR i IN v_emp.FIRST .. v_emp.LAST LOOP
IF v_emp.EXISTS(i) THEN
DBMS_OUTPUT.PUT_LINE(v_emp(i).ename);
END IF;
END LOOP;
END;
/
關鍵方法
EXISTS(n):檢查元素存在(避免 NO_DATA_FOUND)
COUNT:元素個數
FIRST/LAST:首尾下標
NEXT/PRIOR:迭代器模式遍歷稀疏陣列
DELETE(n):刪除指定元素
嵌套表實戰
宣告與初始化(必須)
DECLARE
TYPE nested_type IS TABLE OF VARCHAR2(20);
v_my_nested nested_type := nested_type('aa', 'bb'); -- 建構函式初始化
BEGIN
v_my_nested.EXTEND(3); -- 擴展 3 個元素(變 NULL)
v_my_nested(5) := 'ee'; -- 指定下標賦值
END;
/
持久化至資料表
CREATE TYPE nested_varchar_type AS TABLE OF VARCHAR2(100);
/
CREATE TABLE dept_skills (
dept_id NUMBER,
skills nested_varchar_type
) NESTED TABLE skills STORE AS skills_tab;
VARRAY 實戰
宣告(固定上限)
DECLARE
TYPE varray_type IS VARRAY(100) OF emp.ename%TYPE;
v_arr varray_type := varray_type(); -- 必須初始化
BEGIN
v_arr.EXTEND(100); -- 擴展至上限
-- 填充...
END;
/
集合通用方法速查
| 方法 | 關聯陣列 | 嵌套表 | VARRAY | 說明 |
| EXISTS(n) | ✓ | ✓ | ✓ | 元素是否存在 |
| COUNT | ✓ | ✓ | ✓ | 元素個數 |
| FIRST/LAST | ✓ | ✓ | ✓ | 首/尾下標 |
| NEXT/PRIOR(n) | ✓ | ✓ | ✓ | 迭代器導航 |
| EXTEND(n) | ✗ | ✓ | ✓ | 擴展 n 個 NULL 元素 |
| TRIM(n) | ✗ | ✓ | ✓ | 移除尾部 n 個元素 |
| DELETE(n) | ✓ | ✓ | ✓ | 刪除指定/全部元素 |
選型決策樹
需要持久化至資料庫欄位?
├─ 是 → 固定最大長度且順序重要? → VARRAY
│ └─ 否 → 嵌套表
└─ 否 → 僅記憶體暫存、查找表、快取? → 關聯陣列(首選)
需負數下標或稀疏結構? → 關聯陣列
效能與最佳實踐
- BULK COLLECT + FORALL:批量處理資料庫交互,效能提升數量級
- 記憶體管理:大集合使用後主動
DELETE 釋放 PGA
- 避免逐行處理:集合操作替代隱性游標循環
- 初始化習慣:嵌套表/VARRAY 必須初始化,否則操作報 ORA-06531