標量參數 (NUMBER、VARCHAR2) 只能返回單值。實際統計查詢常需返回「結果集」或「二維數組」,PL/SQL 集合 正是為此設計:一次傳遞多元素,支持整體操作與單元素訪問,靈活高效。
| 類型 | 結構 | 大小限制 | 初始化 | 適用場景 |
|---|---|---|---|---|
| 索引表 (Index-by Table) | 稀疏、無序、Key 為 BINARY_INTEGER | 受限於 Key 範圍 (-2G~+2G) | 無需初始化,直接賦值 | 臨時計算、PL/SQL 內部傳遞、OUT 參數首選 |
| 嵌套表 | 稠密、有序、可存儲於數據庫列 | 無上限 (受存儲限制) | 需構造函數初始化 | 持久化存儲、列屬性 |
| VARRAY | 固定長度、有序 | 定義時指定最大元素數 | 需構造函數初始化 | 已知最大量、順序重要的小集合 |
CREATE OR REPLACE PACKAGE out_param IS
-- 定義元素為 VARCHAR2(50) 的索引表類型
TYPE out_index_table_typ IS TABLE OF VARCHAR2(50) INDEX BY BINARY_INTEGER;
END out_param;
/
關鍵點:OUT 參數的集合類型必須在包中定義,否則編譯報錯 "PLS-00382: expression is of wrong type"。
CREATE OR REPLACE PROCEDURE testPro1 (
in_param IN VARCHAR2,
o_table OUT out_param.out_index_table_typ -- 包名.類型名
) IS
BEGIN
-- 示例:模擬查詢返回多行結果
o_table(1) := 'Row 1 Data';
o_table(2) := 'Row 2 Data';
o_table(100) := 'Sparse Key 100'; -- 稀疏鍵演示
-- 實際業務中可循環賦值:o_table(i) := cursor_rec.col_val;
END testPro1;
/
CallableStatement cs = conn.prepareCall("{call testPro1(?, ?)}");
cs.setString(1, "input_val");
cs.registerOutParameter(2, OracleTypes.ARRAY, "OUT_PARAM.OUT_INDEX_TABLE_TYP");
// 注意:索引表無法直接註冊為 ARRAY,實際常用 REF CURSOR 或嵌套表替代
// 此處演示邏輯,實際生產建議用 SYS_REFCURSOR 返回結果集
cs.execute();
/*
// 若用嵌套表類型 (需 CREATE TYPE 而非包內定義)
Array arr = cs.getArray(2);
Object[] data = (Object[]) arr.getArray();
*/
cs.close();
o_table(dept_id) := dept_name。SYS_REFCURSOR 返回結果集 (通用、標準、驅動支持最好);CREATE TYPE nt_type AS TABLE OF VARCHAR2(50) (嵌套表) 映射 OracleTypes.ARRAY。索引表以「無需初始化、稀疏鍵、包級定義」三大特性,成為 PL/SQL 內部多值傳遞的利器。但跨語言調用 (Java/.NET) 時,首選 SYS_REFCURSOR,兼顧標準化與性能;集合類型更適合 PL/SQL 內部模塊間交互。