首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 函數回傳表類型:物件型別、PIPELINED、集合完整實作

     編輯:Oracle 資料庫相關知識

Oracle Function 要回傳「表」結果集,必須先定義 **物件型別** → **集合型別**,再在 Function 中構建集合回傳。本文提供兩種模式:PIPELINED 流式回傳**(記憶體效率高、支援並行)與**一般集合回傳**(簡單、小資料量)的完整範本。

步驟 1:定義物件型別(對應一列結構)

CREATE OR REPLACE TYPE obj_table AS OBJECT (
    id   INT,
    name VARCHAR2(50)
);

步驟 2:定義集合型別(對應表結構)

CREATE OR REPLACE TYPE t_table IS TABLE OF obj_table;

模式一:PIPELINED FUNCTION(推薦大量資料)

CREATE OR REPLACE FUNCTION f_pipe(p_cnt IN NUMBER)
RETURN t_table PIPELINED
AS
    v_obj obj_table;
BEGIN
    FOR i IN 1 .. p_cnt LOOP
        v_obj := obj_table(i, TO_CHAR(i * i));  -- 建構物件實例
        PIPE ROW(v_obj);                        -- 逐列流式輸出
    END LOOP;
    RETURN;  -- PIPELINED 必須以空 RETURN 結束
END f_pipe;
/

-- 呼叫方式(TABLE() 轉換為關聯式結果集)
SELECT * FROM TABLE(f_pipe(5));

模式二:一般 FUNCTION 回傳集合(適合小資料量)

CREATE OR REPLACE FUNCTION f_normal(p_cnt IN NUMBER)
RETURN t_table
AS
    v_rs t_table := t_table();  -- 必須初始化空集合
BEGIN
    FOR i IN 1 .. p_cnt LOOP
        v_rs.EXTEND;                                    -- 擴展集合大小
        v_rs(v_rs.COUNT) := obj_table(v_rs.COUNT, 'name' || v_rs.COUNT);
    END LOOP;
    RETURN v_rs;
END f_normal;
/

-- 呼叫方式
SELECT * FROM TABLE(f_normal(5));

關鍵差異對比

特性PIPELINED一般集合
記憶體佔用流式,逐列產生,**O(1)**一次構建整個集合,**O(N)**
並行查詢支援 PARALLEL_ENABLE不支援
轉換開銷無中間集合分配需分配完整集合記憶體
適用場景ETL、大量資料轉換、資料泵小筆資料、快速原型、單元測試
RETURN 語法空 RETURN;RETURN collection_var;

進階:Session 級使用者變數替代方案

若需在多個 Function/Procedure 間共享「表變數」,可用 DBMS_SESSION.SET_CONTEXT 搭配 SYS_CONTEXT 實現命名空間變數:

-- 建立 Context 命名空間(需 CREATE ANY CONTEXT 權限)
CREATE OR REPLACE CONTEXT my_ctx USING pkg_ctx;

-- 套件 pkg_ctx 內設定/讀取
DBMS_SESSION.SET_CONTEXT('my_ctx', 'my_table', serialized_collection);
val := SYS_CONTEXT('my_ctx', 'my_table');

實戰呼叫範例(Java JDBC)

CallableStatement cs = conn.prepareCall("{? = call f_pipe(?)}");
cs.registerOutParameter(1, OracleTypes.CURSOR);  -- PIPELINED 實際回傳 CURSOR
cs.setInt(2, 100);
cs.execute();
ResultSet rs = (ResultSet) cs.getObject(1);
while (rs.next()) { ... }

回傳表類型是 Oracle PL/SQL 模組化、資料轉換封裝的核心技術。**PIPELINED + 物件型別 + 集合型別** 是企業級開發標準模式。

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