Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return multiple rows from the stored procedure? (Oracle PL/SQL)

Tags:

sql

oracle

plsql

People also ask

Can procedure return multiple values in PL SQL?

If a stored procedure contains multiple OUT parameters, it can return multiple values to the argument variables stated in the calling PL/SQL code block.

How can I return multiple values from a stored procedure?

In order to fetch the multiple returned values from the Stored Procedure, you need to make use of a variable with data type and size same as the Output parameter and pass it as Output parameter using OUTPUT keyword. You can also make use of the Split function to split the comma separated (delimited) values into rows.

Can Oracle stored procedure return multiple result sets?

To make the migration of other databases to the Oracle Database easier, Oracle Database 12c Release 1 added a new feature called implicit statement result that allows you to return one or more result sets from a stored procedure by using the dbms_sql package.

Can function return multiple rows in Oracle?

Hi, Ideally you should not try to get the multiple row result as how you are trying to. You cannot get the desired result as per the way you are trying to get it. SELECT ven_mod || ': '|| names into l_return from tobject where object_id in (p1_in,p2_in,p3_in,p4_in);


Here is how to build a function that returns a result set that can be queried as if it were a table:

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

I think you want to return a 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;

Update: If you need to call this from SQL, use a table function like @Tony Andrews suggested.


You may use Oracle pipelined functions

Basically, when you would like a PLSQL (or java or c) routine to be the «source» of data -- instead of a table -- you would use a pipelined function.

Simple Example - Generating Some Random Data
How could you create N unique random numbers depending on the input argument?

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;

Suppose we needed three rows for something. We can now do that in one of two ways:

select * from TABLE(gen_numbers(3));

COLUMN_VALUE


       1
       2
       3

or

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

COLUMN_VALUE


       1
       2
       3

pipelied Functions1 pipelied Functions2


If you want to use it in plain SQL, I would let the store procedure fill a table or temp table with the resulting rows (or go for @Tony Andrews approach).
If you want to use @Thilo's solution, you have to loop the cursor using PL/SQL. Here an example: (I used a procedure instead of a function, like @Thilo did)

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;