1

Could some one help me with creating a example, to implement a dynamic query that uses IN clause and populate the results to cursor. The input parameter could be array or string concatenated.

I have been trying a lot but no successful.

Thanks..

General Grievance
  • 4,555
  • 31
  • 31
  • 45
  • 1
    Please refer this: I am also having this issue. http://stackoverflow.com/questions/34497184/oracle-paramterized-query-with-in-clause-return-null-value – Rajesh D Dec 29 '15 at 15:10

1 Answers1

2

Clasic situation everyone has. You can form a Query string dynamically based on your array or sometthing. And use as OPEN CURSOR. .

  DECLARE
    v_mystring VARCHAR(50);
    v_my_ref_cursor sys_refcursor;
    in_string varchar2='''abc'',''bcd''';
    id2 varchar2(10):='123';
        myrecord tablename%rowtype;
  BEGIN

    v_mystring := 'SELECT a.*... from tablename a where name= :id2 and 
                    id in('||in_string||')';

    OPEN v_my_ref_cursor FOR v_mystring USING id2;

    LOOP
      FETCH v_my_ref_cursor INTO myrecord;
      EXIT WHEN v_my_ref_cursor%NOTFOUND;
        ..
      -- your processing
    END LOOP;
    CLOSE v_my_ref_cursor;

  END;

IN clause supports maximum of 1000 items. You can always use a table to join instead. That table might be a Global Temporary Table(GTT) whose data is visible to thats particular session.

Still you can use a nested table also for it(like PL/SQL table)

TABLE() will convert a PL/Sql table as a SQL understandable table object(an object actually)

A simple example of it below.

CREATE TYPE pr AS OBJECT
           (pr  NUMBER);
/
CREATE TYPE prList AS TABLE OF pr;
/

declare
  myPrList prList := prList ();
  cursor lc is 
    select * 
      from (select a.*
              from yourtable a
                   TABLE(CAST(myPrList as prList)) my_list
             where 
                   a.pr = my_list.pr
             order by a.pr desc) ;
  rec lc%ROWTYPE;

BEGIN 
  /*Populate the Nested Table, with whatever collection you have */
  myPrList := prList ( pr(91),
                       pr(80));
  /*
     Sample code: for populating from your TABLE OF NUMBER type 

     FOR I IN 1..your_input_array.COUNT
     LOOP
          myPrList.EXTEND;
          myPrList(I) := pr(your_input_array(I));
     END LOOP;
  */
  open lc;
  loop 
    FETCH lc into rec;
    exit when lc%NOTFOUND; -- Your Exit WHEN condition should be checked afte FETCH iyself!
    dbms_output.put_line(rec.pr);
  end loop;
  close lc;
END;
/
Maheswaran Ravisankar
  • 17,652
  • 6
  • 47
  • 69
  • i wanted a dynamic sql, that i can assign it to a variable and that should contain in-clause. Also the cursor query should be OPEN p_Cursor FOR v_Query USING p_Id, p_StartDt p_Id contains multiple comma values – Dotnet_Ferrari Feb 11 '14 at 07:17
  • hope, the first approach would interest you! do some looping to process your array and form a query string. in my above approach, you can also use the USING, but you cannot bind the IN clause... as it is not supported.. – Maheswaran Ravisankar Feb 11 '14 at 07:19
  • first looks good and easy, but not suitable for my implementation. I need to pass multiple parameters and one of their parameter has multiple ids – Dotnet_Ferrari Feb 11 '14 at 07:24
  • multiple parameters is acheivable.. where as multiple ids you mean, you have a array of ids? – Maheswaran Ravisankar Feb 11 '14 at 07:27
  • yes, i can pass as array from .net I was passing a table type and i get error when passing array or type value parameter – Dotnet_Ferrari Feb 11 '14 at 07:28
  • Yes, thats is a basic problem.. it is not supported. bind variable is always like, the query is always ready after parsing and just waiting for values. FOR IN caluse, the values in the IN clause are actually converted into multiple ORs and always there is limitation for 1000 .. So oracle simply not allows to bind an array because it has to do other parsing.. also you have to understand query with bind variable is supposed to be reusable without hard parsing.. – Maheswaran Ravisankar Feb 11 '14 at 07:30
  • So then i cant pass 4 parameters of which one can contain array/comma separated values .....using cursor? – Dotnet_Ferrari Feb 11 '14 at 07:37
  • comma separated .. if hard coded before opening the cursor is possible. Is there any issues for you to form the IN clause string.. you have no other option :) I wish I can have a chat.. but you dont have 20 reps. – Maheswaran Ravisankar Feb 11 '14 at 07:38
  • I can pass comma separated values to the package... But in the dynamic query, how do i add it? does it accept that parameter in passing values to cursor?? – Dotnet_Ferrari Feb 11 '14 at 07:41
  • Dynamic Query is just a string bro, you can play.. except for IN clause, for other parametrs.. you just do as i did above.. I editted my answer.. a bit.. does that help you? Understand you _CANNOT_ bind like Id IN :invalues – Maheswaran Ravisankar Feb 11 '14 at 07:44
  • @OracleUser, actually you can bind the csv string if you use one of [these tricks](http://stackoverflow.com/questions/13580245/sending-an-array-of-values-to-oracle-procedure-to-use-in-where-in-clause) – A.B.Cade Feb 11 '14 at 09:38