Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to call a stored procedure from another stored procedure in oracle

I have an existing stored procedure that takes 2 parameters and returns back an oracle cursor. The cursor contains about 30 to 60 rows of data.

I want to use the above pre-existing stored procedure in another stored procedure as a table...basically I want to call the pre-existing stored procedure and see if the rows returned back contain a particular value.

For example:

SP 1 = get_data_1 (returns oracle cursor)
SP 2 = get_data_2 

in get_data_2

select count(*) from get_data_1 (pass_input_parms) A where A.ID = '12345'

Conceptually it seems like a trivial thing to do to me however, being new to the oracle world I do not know how to make use of preexisting stored procedures that return cursors.

How would I do this?

like image 754
Reeth Avatar asked Nov 11 '10 15:11

Reeth


1 Answers

You cannot reuse a REF CURSOR from get_data_1 in a subsequent SQL statement because it's just a pointer to a statement handle. The cursor itself contains no data.

You could do something like

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;

As you might imagine, though, this tends to get old relatively quickly. Given that, it tends not to be common in Oracle to have stored procedures that return REF CURSOR parameters except in cases where you are returning a finished view of the data to a client application. If there was a shared view, for example, that both GET_DATA_1 and GET_DATA_2 could query rather than having GET_DATA_2 call GET_DATA_1, that would simplify the program. If GET_DATA_1 was a pipelined table function rather than a procedure that returned a REF CURSOR, then it would be much easier to call GET_DATA_1 from GET_DATA_2.

If you want to get started with pipelined table functions (using the SCOTT schema)

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
like image 134
Justin Cave Avatar answered Sep 27 '22 18:09

Justin Cave