利用函数返回结果集方法总结
返回结果集函数可以将变量值传递给函数得到指定的结果集,优点在于灵活控制结果集变量及输出,不用将sql嵌入到页面代码里,业务逻辑如有更改可以直接在数据库中维护。
现总结三种方法:OBJECT TYPE、OBJECT TYPE+PIPE ROW、RECORD+PIPE ROW
OBJECT TYPE
TYPE定义
create type tp_obj_emp as object(
empno NUMBER(4),
ename VARCHAR2(10),
job VARCHAR2(9),
mgr NUMBER(4),
hiredate DATE,
sal NUMBER(7,2),
comm NUMBER(7,2),
deptno NUMBER(2)
)
create type tp_tab_emp is table of tp_obj_emp;
函数定义
create or replace function f_test_record(p_deptno number) return tp_tab_emp as
v_tab tp_tab_emp;
begin
select tp_obj_emp(empno, ename, job, mgr, hiredate, sal, comm, deptno)
bulk collect
into v_tab
from emp
where deptno = p_deptno;
return v_tab;
end;
调用
SQL> select * from table(f_test_record(10));
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7782 CLARK MANAGER 7839 09-6月 -81 2450 10
7839 KING PRESIDENT 17-11月-81 5000 10
7934 MILLER CLERK 7782 23-1月 -82 1300 10
已用时间: 00: 00: 00.01
OBJECT TYPE+PIPE ROW
TYPE定义
create type tp_obj_emp as object(
empno NUMBER(4),
ename VARCHAR2(10),
job VARCHAR2(9),
mgr NUMBER(4),
hiredate DATE,
sal NUMBER(7,2),
comm NUMBER(7,2),
deptno NUMBER(2)
)
create type tp_tab_emp is table of tp_obj_emp;
函数定义
create or replace function f_test_record_pipe(p_deptno number)
return tp_tab_emp
pipelined as
v_obj tp_obj_emp;
begin
for cur in (select * from emp where deptno = p_deptno) loop
v_obj := tp_obj_emp(cur.empno,
cur.ename,
cur.job,
cur.mgr,
cur.hiredate,
cur.sal,
cur.comm,
cur.deptno);
pipe row(v_obj);
end loop;
end;
调用
SQL> select * from table(f_test_record_pipe(10));
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7782 CLARK MANAGER 7839 09-6月 -81 2450 10
7839 KING PRESIDENT 17-11月-81 5000 10
7934 MILLER CLERK 7782 23-1月 -82 1300 10
已用时间: 00: 00: 00.01
RECORD+PIPE ROW
定义包
create or replace package pkg_pipe_test as
type t_rec_emp is record(
empno number(4),
ename varchar2(10),
job varchar2(9),
mgr number(4),
hiredate date,
sal number(7, 2),
comm number(7, 2),
deptno number(2));
type t_tab_emp is table of t_rec_emp;
function f_test_record_pipe_noc(p_deptno number) return t_tab_emp
pipelined;
end;
create or replace package body pkg_pipe_test is
function f_test_record_pipe_noc(p_deptno number) return t_tab_emp
pipelined as
v_rec t_rec_emp;
begin
for cur in (select * from emp where deptno = p_deptno) loop
v_rec.empno := cur.empno;
v_rec.ename := cur.ename;
v_rec.job := cur.job;
v_rec.mgr := cur.mgr;
v_rec.hiredate := cur.hiredate;
v_rec.sal := cur.sal;
v_rec.comm := cur.comm;
v_rec.deptno := cur.deptno;
pipe row(v_rec);
end loop;
end;
end;
调用
SQL> select * from table(pkg_pipe_test.f_test_record_pipe_noc(10));
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7782 CLARK MANAGER 7839 09-6月 -81 2450 10
7839 KING PRESIDENT 17-11月-81 5000 10
7934 MILLER CLERK 7782 23-1月 -82 1300 10
已用时间: 00: 00: 00.01
总结
对于OBJECT TYPE和OBJECT TYPE+PIPE ROW的方法需要在数据库里定义OBJECT TYPE而RECORD+PIPE ROW需要在包内定义RECORD类型。