您不能在后续SQL语句中重复使用来自get_data_1的REF CURSOR,因为它只是一个指向语句句柄的指针。游标本身不包含数据。
你可以做类似
CREATE PROCEDURE get_data_2(p_cnt OUT NUMBER)
AS
l_rc <<your cursor type>>;
l_rec <<the type your cursor returns>>;
BEGIN
get_data_1(<<parameter 1>>, <<parameter 2>>, l_rc);
p_cnt := 0;
LOOP
FETCH l_rc INTO l_rec;
EXIT WHEN l_rc%NOTFOUND;
IF(l_rec.id = '12345')
THEN
p_cnt := p_cnt + 1;
END IF;
END LOOP;
CLOSE l_rc;
END;
正如你可能想象,不过,这往往会老去相对较快。鉴于此,除非您将完成的数据视图返回给客户端应用程序,否则在Oracle中往往不存在返回REF CURSOR参数的存储过程。例如,如果存在共享视图,则GET_DATA_1和GET_DATA_2都可以查询而不是让GET_DATA_2调用GET_DATA_1,这将简化程序。如果GET_DATA_1是一个流水线表函数而不是返回REF CURSOR的过程,那么从GET_DATA_2调用GET_DATA_1会容易得多。
如果你想开始使用流水线表函数(使用SCOTT模式)
create or replace type emp_obj as object (
empno number,
ename varchar2(10),
job varchar2(9),
mgr number,
hiredate date);
/
create type emp_tbl
as
table of emp_obj;
/
create function emp_pipe(p_deptno IN NUMBER)
return emp_tbl pipelined
is
begin
FOR x IN (SELECT * FROM emp WHERE deptno = p_deptno)
LOOP
PIPE ROW(emp_obj(x.empno,
x.ename,
x.job,
x.mgr,
x.hiredate));
END LOOP;
END;
/
SQL> select * from table(emp_pipe(10));
EMPNO ENAME JOB MGR HIREDATE
---------- ---------- --------- ---------- ---------
7782 CLARK MANAGER 7839 09-JUN-81
7839 KING PRESIDENT 17-NOV-81
7934 MILLER CLERK 7782 23-JAN-82
谢谢,这是有道理的。虽然循环似乎效率低下。你可以指出的任何优秀资源都显示了如何制作流水线功能,然后在另一个SP中使用它们? – Reeth 2010-11-11 15:51:41
@Reeth - 添加了使用流水线表函数的快速演示。 – 2010-11-11 20:12:09