Oracle
 sql >> Database >  >> RDS >> Oracle

Oracle:query dinamica con clausola IN utilizzando il cursore

Situazione classica che tutti hanno. Puoi formare una stringa di query in modo dinamico in base al tuo array o qualcosa del genere. E usa come CURSORE APERTO. .

  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;

La clausola IN supporta un massimo di 1000 elementi. Puoi sempre utilizzare una tabella per unirti. Quella tabella potrebbe essere una Global Temporary Table(GTT) i cui dati sono visibili a quella particolare sessione.

Puoi comunque usare una nested table anche per esso (come la tabella PL/SQL)

TABLE() convertirà una tabella PL/Sql come un oggetto tabella comprensibile SQL (un oggetto effettivamente)

Un semplice esempio di seguito.

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