Home » SQL & PL/SQL » SQL & PL/SQL » Use cursor output in the IN CLAUSE (11.2.1.0)
Use cursor output in the IN CLAUSE [message #647088] Tue, 19 January 2016 03:53 Go to next message
OraFerro
Messages: 433
Registered: July 2011
Senior Member
Hi All,

I have a stored procedure that returns two cursors,
1- the list of direct children of a certain parent id
2- the list of children's children

I need to use the output of the first cursor in the IN clause of the second cursor

create table test_parent 
  (
    id number(2) primary key,
    val varchar(10)
  );

create table test_child1
  (
    id number(2) primary key,
    fk_pid number(2) references test_parent,
    val varchar(10)
  );

create table test_child2
  (
    id number(2) primary key,
    fk_c1id number(2) references test_child1,
    val varchar(10)
  );

insert all
  into test_parent values(1,'p1')
  into test_parent values(2,'p2')
  into test_child1 values(1,1,'c1')
  into test_child1 values(2,1,'c1')
  into test_child1 values(3,2,'c1')
  into test_child1 values(4,2,'c1')
  into test_child2 values(1,1,'c2')
  into test_child2 values(2,1,'c2')
  into test_child2 values(3,2,'c2')
  into test_child2 values(4,3,'c2')
select * from dual;

select * from TEST_CHILD2 where FK_C1ID in (select id from TEST_CHILD1 where FK_PID = 1);



CREATE OR REPLACE PROCEDURE p_get_children(
                            I_parent_ID IN NUMBER, 
                            CUR_child1 OUT SYS_REFCURSOR, 
                            CUR_child2 OUT SYS_REFCURSOR)
is 
  type v_array is varray (6) of number;
  array_id v_array := v_array();
BEGIN
  
open CUR_child1 for select id /*bulk collect into array_id*/
  from TEST_CHILD1 where FK_PID = I_parent_ID;


open CUR_child2 for select id, FK_C1ID, val from TEST_CHILD2  
where FK_C1ID in (select id from TEST_CHILD1 where FK_PID = I_parent_ID); /*<-- this works but I have to repeat the first statement*/
--open CUR_child2 for select id, FK_C1ID, val from TEST_CHILD2  
--where FK_C1ID in (array_id);  <-- here I don't know the correct syntax


END;



Many thanks,
Ferro
Re: Use cursor output in the IN CLAUSE [message #647089 is a reply to message #647088] Tue, 19 January 2016 04:17 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

Quote:
I need to use the output of the first cursor in the IN clause of the second cursor


You can't.

Re: Use cursor output in the IN CLAUSE [message #647090 is a reply to message #647089] Tue, 19 January 2016 04:25 Go to previous messageGo to next message
cookiemonster
Messages: 13975
Registered: September 2008
Location: Rainy Manchester
Senior Member
Ref cursors can only be read once. So if you open a ref cursor and fetch it's contents into a varray you can't then pass that ref cursor back out and have the caller fetch from it.
Since you appear to want to pass both back you have to embed the first the select as a sub-query in the 2nd.
Re: Use cursor output in the IN CLAUSE [message #647091 is a reply to message #647089] Tue, 19 January 2016 04:25 Go to previous messageGo to next message
OraFerro
Messages: 433
Registered: July 2011
Senior Member
Thanks Michel, will stop my trials.
However I belief it would be a very nice improvement, at least we can create and fill an array once from a cursor and then use it in the rest of the SP either in the IN Clause or others!

Thanks again,
Ferro
Re: Use cursor output in the IN CLAUSE [message #647112 is a reply to message #647091] Tue, 19 January 2016 13:48 Go to previous message
Barbara Boehmer
Messages: 9106
Registered: November 2002
Location: California, USA
Senior Member
SCOTT@orcl> CREATE OR REPLACE TYPE v_array AS TABLE OF NUMBER;
  2  /

Type created.

SCOTT@orcl> SHOW ERRORS
No errors.
SCOTT@orcl> CREATE OR REPLACE PROCEDURE p_get_children
  2    (i_parent_id IN	NUMBER,
  3  	cur_child1  OUT SYS_REFCURSOR,
  4  	cur_child2  OUT SYS_REFCURSOR)
  5  is
  6    array_id v_array := v_array();
  7  BEGIN
  8    SELECT id BULK COLLECT INTO array_id
  9    FROM   test_child1
 10    WHERE  fk_pid = i_parent_id;
 11  
 12    OPEN cur_child1 FOR
 13  	 SELECT * FROM TABLE (array_id);
 14  
 15    OPEN cur_child2 FOR
 16  	 SELECT id, fk_c1id, val
 17  	 FROM	test_child2, TABLE (array_id)
 18  	 WHERE	fk_c1id = COLUMN_VALUE;
 19  END;
 20  /

Procedure created.

SCOTT@orcl> SHOW ERRORS
No errors.
SCOTT@orcl> VARIABLE child1_cur REFCURSOR
SCOTT@orcl> VARIABLE child2_cur REFCURSOR
SCOTT@orcl> EXEC p_get_children (1, :child1_cur, :child2_cur)

PL/SQL procedure successfully completed.

SCOTT@orcl> PRINT child1_cur

COLUMN_VALUE
------------
           1
           2

2 rows selected.

SCOTT@orcl> PRINT child2_cur

        ID    FK_C1ID VAL
---------- ---------- ----------
         1          1 c2
         2          1 c2
         3          2 c2

3 rows selected.

Previous Topic: ora-12096
Next Topic: db link between 10g and 12c
Goto Forum:
  


Current Time: Thu Jun 25 15:07:24 CDT 2026