如何从存储过程返回多行? (Oracle PL / SQL)

我想用一个参数创build一个存储过程,这将根据参数返回不同的logging集。 有什么办法做到这一点? 我可以从普通的SQL调用它吗?

下面是如何构build一个函数,返回一个可以被查询的结果集,就像它是一个表一样:

SQL> create type emp_obj is object (empno number, ename varchar2(10)); 2 / Type created. SQL> create type emp_tab is table of emp_obj; 2 / Type created. SQL> create or replace function all_emps return emp_tab 2 is 3 l_emp_tab emp_tab := emp_tab(); 4 n integer := 0; 5 begin 6 for r in (select empno, ename from emp) 7 loop 8 l_emp_tab.extend; 9 n := n + 1; 10 l_emp_tab(n) := emp_obj(r.empno, r.ename); 11 end loop; 12 return l_emp_tab; 13 end; 14 / Function created. SQL> select * from table (all_emps); EMPNO ENAME ---------- ---------- 7369 SMITH 7499 ALLEN 7521 WARD 7566 JONES 7654 MARTIN 7698 BLAKE 7782 CLARK 7788 SCOTT 7839 KING 7844 TURNER 7902 FORD 7934 MILLER 

我想你想要返回一个REFCURSOR:

 create function test_cursor return sys_refcursor is c_result sys_refcursor; begin open c_result for select * from dual; return c_result; end; 

更新 :如果你需要从SQL调用这个,使用@Tony Andrewsbuild议的表函数。

您可以使用Oraclestream水线function

基本上,当你想要一个PLSQL(或者java或者c)例程作为数据的“源代码”而不是一个表格时,你可以使用stream水线function。

简单的例子 – 生成一些随机数据
你怎么能根据input参数创buildN个唯一的随机数字?

 create type array as table of number; create function gen_numbers(n in number default null) return array PIPELINED as begin for i in 1 .. nvl(n,999999999) loop pipe row(i); end loop; return; end; 

假设我们需要三行的东西。 我们现在可以通过以下两种方式之一来实现

 select * from TABLE(gen_numbers(3)); 

COLUMN_VALUE


  1 2 3 

要么

 select * from TABLE(gen_numbers) where rownum <= 3; 

COLUMN_VALUE


  1 2 3 

pipe道function1 pipe道function2

如果你想在普通的SQL中使用它,我会让存储过程用结果行填充表或临时表(或者@Tony Andrews方法)。
如果你想使用@ Thilo的解决scheme,你必须使用PL / SQL来循环游标。 这里是一个例子:(我使用了一个程序而不是像@Thilo那样的函数)

 create or replace procedure myprocedure(retval in out sys_refcursor) is begin open retval for select TABLE_NAME from user_tables; end myprocedure; declare myrefcur sys_refcursor; tablename user_tables.TABLE_NAME%type; begin myprocedure(myrefcur); loop fetch myrefcur into tablename; exit when myrefcur%notfound; dbms_output.put_line(tablename); end loop; close myrefcur; end; 
 create procedure <procedure_name>(p_cur out sys_refcursor) as begin open p_cur for select * from <table_name> end;