一 概述:
1、管道函数即是可以返回行集合(可以使嵌套表nested table 或数组 varray)的函数,我们可以像查询物理表一样查询它或者将其
赋值给集合变量。
2、管道函数为并行执行,在普通的函数中使用dbms_output输出的信息,需要在服务器执行完整个函数后一次性的返回给客户端。如果需要在客户端
实时的输出函数执行过程中的一些信息,在oracle9i以后可以使用管道函数(pipeline function)。
3、关键字PIPELINED表明这是一个Oracle管道函数,oracle管道函数的返回值类型必须为集合,在函数中,PIPE ROW语句被用来返回该集合的单个元
素,函数以一个空的RETURN 语句结束,以表明它已经完成。
4、由于管道函数的并发多管道流式设计以及实时返回查询结果而去除了中间环节因此可以带来可观的性能提升。
二、如何编写管道函数:
例1:
- CREATE OR REPLACE PACKAGE pkg1 AS
- TYPE numset_t IS TABLE NUMBER;
- FUNCTION f1(x NUMBER) RETURN numset_t PIPELINED;
- END pkg1;
CREATE OR REPLACE PACKAGE pkg1 AS
TYPE numset_t IS TABLE NUMBER;
FUNCTION f1(x NUMBER) RETURN numset_t PIPELINED;
END pkg1;
- CREATE OR REPLACE PACKAGE BODY pkg1 AS
- FUNCTION f1(x NUMBER) RETURN numset_t PIPELINED IS
- BEGIN
- FOR i IN 1..x LOOP
- PIPE ROW(i);
- END LOOP;
- RETURN;
- END;
- END pkg1;
CREATE OR REPLACE PACKAGE BODY pkg1 AS
FUNCTION f1(x NUMBER) RETURN numset_t PIPELINED IS
BEGIN
FOR i IN 1..x LOOP
PIPE ROW(i);
END LOOP;
RETURN;
END;
END pkg1;
SELECT * FROM TABLE(pkg1.f1(5));
COLUMN_VALUE------------------------
1
2
3
4
5
三 管道函数用于数据转换:
例2:管道函数可以和常规函数一样接收任何参数,下面的管道函数中参数为ref cursor。
- CREATE OR REPLACE PACKAGE refcur_pkg IS
- TYPE refcur_t IS REF CURSOR RETURN emp%ROWTYPE;
- TYPE outrec_typ IS RECORD (
- var_num NUMBER(6),
- var_char1 VARCHAR2(30),
- var_char2 VARCHAR2(30));
- TYPE outrecset IS TABLE OF outrec_typ;
- FUNCTION f_trans(p refcur_t)
- RETURN outrecset PIPELINED;
- END refcur_pkg;
CREATE OR REPLACE PACKAGE refcur_pkg IS
TYPE refcur_t IS REF CURSOR RETURN emp%ROWTYPE;
TYPE outrec_typ IS RECORD (
var_num NUMBER(6),
var_char1 VARCHAR2(30),
var_char2 VARCHAR2(30));
TYPE outrecset IS TABLE OF outrec_typ;
FUNCTION f_trans(p refcur_t)
RETURN outrecset PIPELINED;
END refcur_pkg;
- CREATE OR REPLACE PACKAGE BODY refcur_pkg IS
- FUNCTION f_trans(p refcur_t)
- RETURN outrecset PIPELINED IS
- out_rec outrec_typ;
- in_rec p%ROWTYPE;
- BEGIN
- LOOP
- FETCH p INTO in_rec;
- EXIT WHEN p%NOTFOUND;
- -- first row
- out_rec.var_num := in_rec.empno;
- out_rec.var_char1 := in_rec.ename;
- out_rec.var_char2 := in_rec.mgr;
- PIPE ROW(out_rec);
- -- second row
- out_rec.var_num := in_rec.deptno;
- out_rec.var_char1 := in_rec.deptno;
- out_rec.var_char2 := in_rec.job;
- PIPE ROW(out_rec);
- END LOOP;
- CLOSE p;
- RETURN;
- END;
- END refcur_pkg;
CREATE OR REPLACE PACKAGE BODY refcur_pkg IS
FUNCTION f_trans(p refcur_t)
RETURN outrecset PIPELINED IS
out_rec outrec_typ;
in_rec p%ROWTYPE;
BEGIN
LOOP
FETCH p INTO in_rec;
EXIT WHEN p%NOTFOUND;
-- first row
out_rec.var_num := in_rec.empno;
out_rec.var_char1 := in_rec.ename;
out_rec.var_char2 := in_rec.mgr;
PIPE ROW(out_rec);
-- second row
out_rec.var_num := in_rec.deptno;
out_rec.var_char1 := in_rec.deptno;
out_rec.var_char2 := in_rec.job;
PIPE ROW(out_rec);
END LOOP;
CLOSE p;
RETURN;
END;
END refcur_pkg;
SELECT * FROM TABLE(
refcur_pkg.f_trans(CURSOR(SELECT * FROM emp WHERE empno=7782)));
VAR_NUM VAR_CHAR1 VAR_CHAR2
---------- ------------------------------ ------------------------------
7782 CLARK 7839
10 10 MANAGER
---------------------------------------
By Dylan.