Search code examples
oracledynamicdatabase-cursorin-clause

Oracle: Dynamic query with IN clause using cursor


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..


Solution

  • 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;
    /