Oracle 函數原生支援回傳標量值,若需回傳「表格型態」結果集,早期常用 REF CURSOR 搭配 Package 實現,但無法直接在 SQL 中以 SELECT * FROM function() 形式呼叫。Oracle 9i 引入 管道化表函數 完美解決此問題。
PIPELINED 關鍵字。PIPE ROW(...) 逐行輸出,最後以空 RETURN; 結束。TABLE(function_name) 將管道流轉為虛擬表。CREATE TABLE tb1 (k NUMBER, v VARCHAR2(10));
INSERT INTO tb1 VALUES (100, 'aaa');
INSERT INTO tb1 VALUES (200, 'bbb');
INSERT INTO tb1 VALUES (200, 'ccc');
CREATE TYPE row_type1 AS OBJECT (k NUMBER, v VARCHAR2(10));
CREATE TYPE table_type1 AS TABLE OF row_type1;
CREATE OR REPLACE FUNCTION fun1
RETURN table_type1 PIPELINED AS
v_row row_type1;
BEGIN
FOR myrow IN (SELECT k, v FROM tb1) LOOP
v_row := row_type1(myrow.k, myrow.v);
PIPE ROW(v_row);
END LOOP;
RETURN;
END;
/
SELECT * FROM TABLE(fun1);
-- 結果:
-- K V
-- 100 aaa
-- 200 bbb
-- 200 ccc
CREATE OR REPLACE FUNCTION fun1(p_k IN NUMBER)
RETURN table_type1 PIPELINED AS
v_row row_type1;
BEGIN
FOR myrow IN (SELECT k, v FROM tb1 WHERE k = p_k) LOOP
v_row := row_type1(myrow.k, myrow.v);
PIPE ROW(v_row);
END LOOP;
RETURN;
END;
/
SELECT * FROM TABLE(fun1(100));
PARALLEL_ENABLE 提升並行效能。CREATE OR REPLACE PACKAGE mypk AS
TYPE t_cursor IS REF CURSOR;
PROCEDURE proc(p_name VARCHAR2, p_cur OUT t_cursor, p_id NUMBER);
END;
/
-- 需在 PL/SQL 區塊或應用層透過游標處理,無法直接 SELECT * FROM ...
管道化表函數讓 PL/SQL 函數能像資料表一樣被 SQL 直接查詢,極大擴展了函數的複用性與組合性,是 Oracle 進階開發必備技能。