Parameterized Cursor

Can I define a parameterized cursor which takes in clause as a parameter.
e.g
declare
someVariable varchar2(100);
Cursor c1 is select emp.name,emp.dept_id
from emp
where emp.id in someVariable;
/* emp.id is a varchar2 data type*/
Is it possible to do something like this...
Rohit

If I've read your question correctly then if you are looking for emp.id to be IN rather than = then you would need:
declare
-- someVariable varchar2(100);
Cursor c1 (P_emp_id in emp.id%type) is
select emp.name,emp.dept_id
from emp
where emp.id in (P_emp_id);
otherwise use WHERE emp.id = p_emp_id. If you are passing in someVariable as p_emp_id then emp.id (using your example) must also be of VARCHAR2 datatype or this won't work.

Similar Messages

  • Improve performance select in parameterized cursor.

    DECLARE
    CURSOR cur_inv_bal_ship_from(
    l_num_qty_multiplier gfstmr4_eop_transaction_type.
    inventory_multiplier_num%TYPE,
    l_str_inventory_type gfstmr9_eop_txn_rule.inventory_type_code%TYPE,
    l_str_type_code gfstmr9_eop_txn_rule.txn_type_code%TYPE)IS
    SELECT /*+ USE_NL(EPP PI EPC) */ epc.currency_code,
    SUM(ROUND(l_num_qty_multiplier * pi.inventory_qty * epc.cost_amt,2)) cost_amt
    FROM gfstm62_eop_plant_part epp,
    gfstm64_plant_inventory pi,
    gfstm60_eop_part_cost epc
    WHERE epp.gsdb_site_code = i_str_gsdb_site_code
    AND epp.end_of_period_date = i_dt_end_of_period_date
    AND pi.inventory_type_code = l_str_inventory_type
    AND pi.txn_type_code = l_str_type_code
    AND pi.gsdb_shipped_from_code = i_str_gsdb_site_code
    AND epc.rate_set_code = i_str_rate_set_code
    AND epc.financial_element_type_code = i_str_financial_element_code
    AND pi.plant_eop_part_sakey = epp.eop_plant_part_sakey
    AND pi.plant_inventory_sakey = epc.plant_inventory_sakey
    GROUP BY currency_code;
    BEGIN
    FOR l_num_index IN i_tab_inv_txn_rule.FIRST .. i_tab_inv_txn_rule.LAST
    LOOP
    --Checking for ship from flag equal to 'Y'
    IF i_tab_inv_txn_rule(l_num_index).ship_from_flag = g_con_y THEN
    --Looping through ship from cursor
    FOR l_rec_inv_bal_from IN cur_inv_bal_ship_from(
    i_tab_inv_txn_rule(l_num_index).qty_multiplier_num,
    i_tab_inv_txn_rule(l_num_index).inventory_type_code,
    i_tab_inv_txn_rule(l_num_index).txn_type_code)
    LOOP
    --Incrementing index value
    l_num_index1 := (l_num_index1 + 1);
    --Assigning cursor values to PLSQL table
    l_tab_inv_bal(l_num_index1).currency_code :=
    l_rec_inv_bal_from.currency_code;
    l_tab_inv_bal(l_num_index1).cost_amt :=
    l_rec_inv_bal_from.cost_amt;
    --Loop closing for ship from cursor
    END LOOP;
    END LOOP;
    END;
    The select query in the parameterized cursor taking long time. Below is the link in which i have shown the trace. Please let me know the way to improve performance.
    http://performancetuning1978.blogspot.com/p/performance-tuning.html
    thanks,
    Vinodh

    Hello,
    your performance-tuning picture doesn't say much. How do your tables look like, how many rows, oracle version.
    Why do you use nested-lööps as a hint?

  • Parameterized cursor for varient Table name?

    Hi all,
    I am using Oracle 9i and have a cursor defined as :-
    Code:
    CREATE PROCEDURE Proc_Abc
    AS
    CURSOR
    My_Cursor (UserName VARCHAR) IS
    SELECT Emp_Name, Salary FROM Employee_Table
    WHERE User_Name = UserName;     
    (Rest of the code)
    This code is working perfectly, but if I try to provide the table name through the cursor variable, it gives an error
    Below is the code that I am writing to pass table name through variable:-
    Code:
    CREATE PROCEDURE Proc_Abc
    AS
    CURSOR
    My_Cursor (TableName VARCHAR, UserName VARCHAR) IS
    SELECT Emp_Name, Salary FROM TableName
    WHERE User_Name = UserName;     
    (Rest of the code)
    All the tables that I need to pass through cursor variables have the same fields and are all pre known to me, thats why "SELECT Emp_Name, Salary " is remaining common throughout.
    Please suggest how can I make a cursor with variant tables?
    Thanks in advance.

    The following procedure compares between two tables and then it picking the column from all_tab_column table and finally execute the SELECT statement to compare the data between this two table. But, you can proceed your program taking help from this -
    satyaki>ed
    Wrote file afiedt.buf
      1  create or replace procedure compr_tab_dat(TAR_TAB IN VARCHAR2,
      2                                            TAR_UID IN VARCHAR2,
      3                                            SRC_TAB IN VARCHAR2,
      4                                            SRC_UID IN VARCHAR2)
      5  is
      6   cursor c1
      7   is
      8    select column_name
      9    from (
    10           select column_name,column_id
    11           from all_tab_columns
    12           where table_name = SRC_TAB
    13           and   owner = SRC_UID
    14           intersect
    15           select column_name,column_id
    16           from all_tab_columns
    17           where table_name = TAR_TAB
    18           and   owner = TAR_UID
    19         )
    20     order by column_id;
    21   cursor c_count
    22   is
    23     select count(column_name) as c_cnt
    24     from (
    25             select column_name
    26             from all_tab_columns
    27             where table_name = SRC_TAB
    28             and   owner = SRC_UID
    29             intersect
    30             select column_name
    31             from all_tab_columns
    32             where table_name = TAR_TAB
    33             and   owner = TAR_UID
    34           );
    35   rec1 c1%rowtype;
    36   rec2 c1%rowtype;
    37   rec3 c1%rowtype;
    38   rec6 c_count%rowtype;
    39   cnt  number(10);
    40   cnt1  number(10);
    41   str  varchar2(32000);
    42   --str  clob;
    43  BEGIN
    44     cnt := 0;
    45     cnt1 := 1;
    46     dbms_output.enable(10000000);
    47     for rec6 in c_count
    48     loop
    49      cnt := rec6.c_cnt;
    50     end loop;
    51     if cnt = 0 then
    52        dbms_output.put_line('No matched columns found.... ');
    53     else
    54        dbms_output.put_line('UnMatched Datas Are-- ');
    55           str:='declare '||
    56          '  cursor c3 '||
    57          '  is '||
    58          '    select ';
    59           open c1;
    60           loop
    61             fetch c1 into rec1;
    62             exit when c1%notfound;
    63             if cnt = cnt1 then
    64                str:= str||rec1.column_name;
    65             elsif cnt1<cnt then
    66               str:= str||rec1.column_name||',';
    67             end if;
    68             cnt1 := cnt1 + 1;
    69           end loop;
    70           close c1;
    71           str:=str||' from '||SRC_TAB||
    72                ' minus '||
    73                ' select ';
    74           cnt1:=1;
    75           open c1;
    76           loop
    77             fetch c1 into rec2;
    78             exit when c1%notfound;
    79             if cnt = cnt1 then
    80                str:= str||rec2.column_name;
    81             elsif cnt1<cnt then
    82                str:= str||rec2.column_name||',';
    83             end if;
    84             cnt1 := cnt1 + 1;
    85           end loop;
    86           close c1;
    87           str:=str||' from '||TAR_TAB||';'||
    88                ' r3 c3%rowtype; '||
    89                ' begin '||
    90                '   for r3 in c3 '||
    91                '   loop '||
    92                '     dbms_output.put_line(';
    93           cnt1:=1;
    94           open c1;
    95           loop
    96             fetch c1 into rec3;
    97             exit when c1%notfound;
    98             if cnt = cnt1 then
    99                str:= str||' r3.'||rec3.column_name;
    100             elsif cnt1<cnt then
    101                str:= str||' r3.'||rec3.column_name||
    102                     '||'',''||';
    103                cnt1 := cnt1 + 1;
    104             end if;
    105           end loop;
    106           close c1;
    107           str:=str||');'||
    108                ' end loop;'||
    109                ' exception '||
    110                '   when others then '||
    111                '     dbms_output.put_line(sqlerrm); '||
    112                ' end; ';
    113     end if;
    114     execute immediate(str);
    115     --dbms_output.put_line(str);
    116  exception
    117    when others then
    118      dbms_output.put_line(sqlerrm);
    119* END;
    120  /
    Procedure created.
    satyaki>
    satyaki>
    satyaki>
    satyaki>create table emp_t
      2     as
      3       select * from emp
      4       where rownum < 5;
    Table created.
    satyaki>
    satyaki>
    satyaki>desc emp;
    Name                                      Null?    Type
    EMPNO                                     NOT NULL NUMBER(4)
    ENAME                                              VARCHAR2(10)
    JOB                                                VARCHAR2(9)
    MGR                                                NUMBER(4)
    HIREDATE                                           DATE
    SAL                                                NUMBER(7,2)
    COMM                                               NUMBER(7,2)
    DEPTNO                                             NUMBER(2)
    satyaki>
    satyaki>
    satyaki>desc emp_t;
    Name                                      Null?    Type
    EMPNO                                              NUMBER(4)
    ENAME                                              VARCHAR2(10)
    JOB                                                VARCHAR2(9)
    MGR                                                NUMBER(4)
    HIREDATE                                           DATE
    SAL                                                NUMBER(7,2)
    COMM                                               NUMBER(7,2)
    DEPTNO                                             NUMBER(2)
    satyaki>set lin 1000
    satyaki>
    satyaki>select * from emp;
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
          7369 SMITH      CLERK           7902 17-DEC-80        800                    20
          7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
          7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
          7566 JONES      MANAGER         7839 02-APR-81       2975                    20
          7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         30
          7698 BLAKE      MANAGER         7839 01-MAY-81       2850                    30
          7782 CLARK      MANAGER         7839 09-JUN-81       2450                    10
          7788 SCOTT      ANALYST         7566 19-APR-87       3000                    20
          7839 KING       PRESIDENT            17-NOV-81       5000                    10
          7844 TURNER     SALESMAN        7698 08-SEP-81       1500          0         30
          7876 ADAMS      CLERK           7788 23-MAY-87       1100                    20
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
          7900 JAMES      CLERK           7698 03-DEC-81        950                    30
          7902 FORD       ANALYST         7566 03-DEC-81       3000                    20
          7934 MILLER     CLERK           7782 23-JAN-82       1300                    10
    14 rows selected.
    satyaki>
    satyaki>
    satyaki>select * from emp_t;
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
          7369 SMITH      CLERK           7902 17-DEC-80        800                    20
          7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
          7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
          7566 JONES      MANAGER         7839 02-APR-81       2975                    20
    satyaki>
    satyaki>
    satyaki>set serveroutput on
    satyaki>
    satyaki>
    satyaki>begin
      2   compr_tab_dat('EMP_T','SCOTT','EMP','SCOTT');
      3  end;
      4  /
    No matched columns found....
    ORA-06535: statement string in EXECUTE IMMEDIATE is NULL or 0 length
    PL/SQL procedure successfully completed.
    satyaki>
    satyaki>
    satyaki>sho user;
    USER is "TRG2"
    satyaki>
    satyaki>
    satyaki>
    satyaki>
    satyaki>begin
      2       compr_tab_dat('EMP_T','TRG2','EMP','TRG2');
      3     end;
      4      /
      5  .
    satyaki>
    satyaki>ed
    Wrote file afiedt.buf
      1  begin
      2       compr_tab_dat('EMP_T','TRG2','EMP','TRG2');
      3* end;
    satyaki>/
    UnMatched Datas Are--
    7654,MARTIN,SALESMAN,7698,28-SEP-81,1250,1400,30
    7698,BLAKE,MANAGER,7839,01-MAY-81,2850,,30
    7782,CLARK,MANAGER,7839,09-JUN-81,2450,,10
    7788,SCOTT,ANALYST,7566,19-APR-87,3000,,20
    7839,KING,PRESIDENT,,17-NOV-81,5000,,10
    7844,TURNER,SALESMAN,7698,08-SEP-81,1500,0,30
    7876,ADAMS,CLERK,7788,23-MAY-87,1100,,20
    7900,JAMES,CLERK,7698,03-DEC-81,950,,30
    7902,FORD,ANALYST,7566,03-DEC-81,3000,,20
    7934,MILLER,CLERK,7782,23-JAN-82,1300,,10
    PL/SQL procedure successfully completed.N.B.: May be Any other member can come with much shorter or better technique than this one. But, according to your requirement - i'm posting it. Hope this will help you, or atleast give you some idea.
    Regards.
    Satyaki De.

  • Parameters cursor

    I am learning how to use paramters with cursors and i am getting the below error. Can someone point me where i made the mistake and how i can fix it. thanks a bunch
    declare
    cursor c_vendor(v_state in vendaddr.astate%type)
      is
         select aphone,astate, azipcode, vendor
          from vendaddr
          where astate = v_state;
    begin
        for r_vendor in c_vendor
         loop
            dbms_output.put_line(r.vendor.aphone);
        end loop;
    end;
    ORA-06550: line 8, column 21:
    PLS-00306: wrong number or types of arguments in call to 'C_VENDOR'
    ORA-06550: line 8, column 5:
    PL/SQL: Statement ignored

    You are missing a parameter in this line:
       for r_vendor in c_vendor(whereisyourparameter)C.

  • How to make the cursor global if it has parameters that would be passed through calling environment

    What I am trying to do is:
    1. Pass two dates "p_start_date" and "p_end_date" to a procedure "calc_percnt". Based on these two dates the procedure creates a collection that has ticket info between the date range provided.
    2. Iterate through this collection to find out the number of tickets that took less than 4 hrs (p_count_4), less than 8 hours (p_count_8), less than 12 hours(p_count_12) and less than 24 hours (24).
    3. I want to move the logic of the  above point 2 (also mentioned between dotted lines in the below mentioned code) to a function and call that function.
    4. For the above point 3 I will have to create a function which will accept a collection variable something like this:
    create or replace cal_perc (collection_var total_tckt_colcn) .... 
    I cannot do this because total_tckt_colcn needs to be declared
    5. I cannot make the cursor and collection type as global by putting them in package specification because of the condition in cursor:
    WHERE created_date >= p_start_date AND created_date < (p_end_date + interval '1' DAY)
    it gives the error as "p_start_date"  and "p_end_date" needs to be declared.
    What is the best way to do this????
    create or replace
    PROCEDURE calc_percnt(
      p_start_date IN N01.cc_ticket_info.LAST_CHANGED%type ,
      p_end_date   IN N01.cc_ticket_info.LAST_CHANGED%type ,
    AS
      v_start_date N01.cc_ticket_notes.LAST_UPDATED_STAMP%type;
      v_end_date N01.cc_ticket_notes.LAST_UPDATED_STAMP%type;
      CURSOR cur_total_tckt
      IS
      SELECT  * from
      WHERE created_date >= p_start_date AND created_date < (p_end_date + interval '1' DAY)
    type total_tckt_colcn
    IS
      TABLE OF cur_total_tckt%rowtype;
      total_tckt_col total_tckt_colcn;
      total_coach_col total_tckt_colcn;
    BEGIN
      total_tckt_col  := total_tckt_colcn ();
      OPEN cur_total_tckt;
      LOOP
      FETCH cur_total_tckt bulk collect INTO total_tckt_col limit 100;
    END LOOP;
      EXIT
      WHEN (cur_total_tckt%NOTFOUND);
      END LOOP ;
      CLOSE cur_total_tckt;
    -- ---I want to move the following code in a function which finds the time required to close the ticket and increment the counter ------
    FOR i IN total_tckt_col .first..total_tckt_col .last
      LOOP
      no_of_seconds       := calc_time_diff(total_coach_col(i).created_date, total_coach_col(i).closed_date);
      IF (no_of_seconds    < 14400) THEN
      p_count_4          := p_count_4  + 1;
      p_count_8          := p_count_8  + 1;
      p_count_12         := p_count_12 + 1;
      p_count_24         := p_count_24 + 1;
      ELSIF (no_of_seconds < 28800) THEN
      p_count_8          := p_count_8  + 1;
      p_count_12         := p_count_12 + 1;
      p_count_24         := p_count_24 + 1;
      ELSIF (no_of_seconds < 43200) THEN
      p_count_12         := p_count_12 + 1;
      p_count_24         := p_count_24 + 1;
      ELSIF (no_of_seconds < 86400) THEN
      p_count_24         := p_count_24 + 1;
      END IF;
      END LOOP;
    END calc_percnt;

    I cannot add cursor definition to package because  of the following condition:
    WHERE created_date >= p_start_date AND created_date < (p_end_date + interval '1' DAY)
    it gives me an error: "p_start_date"  and "p_end_date" needs to be declared.
    p_start_date and p_end_date are parameters that would be passed by the user.
    Parameterized cursor to the rescue:
    I have changed my cursor definition to:
    create or replace
    PACKAGE ES_REPORTS AS
    CURSOR cur_total_tckt (p_start_date n01.cc_ticket_status_history.created_date%type, p_end_date n01.cc_ticket_status_history.created_date%type)
      IS
      SELECT  t.ticket_id ticket_id , t.created_date created_date, t.created_by created_by, t.ticket_status ticket_status, t.last_changed last_changed, h.closed_date
      FROM n01.cc_ticket_info t
      inner join
      (SELECT  ticket_id , MAX(created_date) closed_date
      FROM n01.cc_ticket_status_history
      WHERE ticket_status = 'CLOSED' AND created_date >= p_start_date AND created_date < (p_end_date + interval '1' DAY)
      GROUP BY ticket_id
      ) h
      on (t.ticket_id         = h.ticket_id)
      WHERE (t. ticket_status = 'NOTIFIED' OR t.ticket_status = 'CLOSED') AND t.last_changed >= p_start_date AND t.last_changed < (p_end_date + interval '1' DAY);
    END ES_REPORTS;
    Not sure if it is good programing practice though?

  • Can I use Bulk Collect results as input parameter for another cursor

    MUSIC            ==> remote MUSIC_DB database, MUSIC table has 60 million rows
    PRICE_DATA ==> remote PRICING_DB database, PRICE_DATE table has 1 billion rows
    These two table once existed in same database, but size of database exceeded available hardware size and hardware budget, so the PRICE_DATA table was moved to another Oracle database.  I need to create a single report that combines data from both of these tables, and a distributed join with DRIVING_SITE hint will not work because the size of both table is too large to push to one DRIVING_SITE location, so I wrote this PLSQL block to process in small blocks.
    QUESTION: how can use bulk collect from one cursor and pass that bulk collected information as input to second cursor without specifically listing each cell of the PLSQL bulk collection?  See sample pseudo-code below, I am trying to determine more efficient way to code than hard-coding 100 parameter names into 2nd cursor.
    NOTE: below is truly pseudo-code, I had to change the names of everything to adhere to NDA, but below works and is fast enough for my purposes, but if I want to change from 100 input parameters to 200, I have to add more hard-coded values.  There has got to be a better way.
    DECLARE
         -- define cursor that retrieves distinct SONG_IDs from MUSIC table in remote music database
         CURSOR C_CURRENT_MUSIC
         IS
        select distinct SONG_ID
        from MUSIC@MUSIC_DB
        where PRODUCTION_RELEASE=1
         /*  define a parameterized cursor that accepts 100 SONG_IDs and retrieves
              required pricing information
         CURSOR C_get_music_price_data
                   P_SONG_ID_001 NUMBER, P_SONG_ID_002 NUMBER, P_SONG_ID_003 NUMBER, P_SONG_ID_004 NUMBER, P_SONG_ID_005 NUMBER, P_SONG_ID_006 NUMBER, P_SONG_ID_007 NUMBER, P_SONG_ID_008 NUMBER, P_SONG_ID_009 NUMBER, P_SONG_ID_010 NUMBER,
                   P_SONG_ID_011 NUMBER, P_SONG_ID_012 NUMBER, P_SONG_ID_013 NUMBER, P_SONG_ID_014 NUMBER, P_SONG_ID_015 NUMBER, P_SONG_ID_016 NUMBER, P_SONG_ID_017 NUMBER, P_SONG_ID_018 NUMBER, P_SONG_ID_019 NUMBER, P_SONG_ID_020 NUMBER,
                   P_SONG_ID_021 NUMBER, P_SONG_ID_022 NUMBER, P_SONG_ID_023 NUMBER, P_SONG_ID_024 NUMBER, P_SONG_ID_025 NUMBER, P_SONG_ID_026 NUMBER, P_SONG_ID_027 NUMBER, P_SONG_ID_028 NUMBER, P_SONG_ID_029 NUMBER, P_SONG_ID_030 NUMBER,
                   P_SONG_ID_031 NUMBER, P_SONG_ID_032 NUMBER, P_SONG_ID_033 NUMBER, P_SONG_ID_034 NUMBER, P_SONG_ID_035 NUMBER, P_SONG_ID_036 NUMBER, P_SONG_ID_037 NUMBER, P_SONG_ID_038 NUMBER, P_SONG_ID_039 NUMBER, P_SONG_ID_040 NUMBER,
                   P_SONG_ID_041 NUMBER, P_SONG_ID_042 NUMBER, P_SONG_ID_043 NUMBER, P_SONG_ID_044 NUMBER, P_SONG_ID_045 NUMBER, P_SONG_ID_046 NUMBER, P_SONG_ID_047 NUMBER, P_SONG_ID_048 NUMBER, P_SONG_ID_049 NUMBER, P_SONG_ID_050 NUMBER,
                   P_SONG_ID_051 NUMBER, P_SONG_ID_052 NUMBER, P_SONG_ID_053 NUMBER, P_SONG_ID_054 NUMBER, P_SONG_ID_055 NUMBER, P_SONG_ID_056 NUMBER, P_SONG_ID_057 NUMBER, P_SONG_ID_058 NUMBER, P_SONG_ID_059 NUMBER, P_SONG_ID_060 NUMBER,
                   P_SONG_ID_061 NUMBER, P_SONG_ID_062 NUMBER, P_SONG_ID_063 NUMBER, P_SONG_ID_064 NUMBER, P_SONG_ID_065 NUMBER, P_SONG_ID_066 NUMBER, P_SONG_ID_067 NUMBER, P_SONG_ID_068 NUMBER, P_SONG_ID_069 NUMBER, P_SONG_ID_070 NUMBER,
                   P_SONG_ID_071 NUMBER, P_SONG_ID_072 NUMBER, P_SONG_ID_073 NUMBER, P_SONG_ID_074 NUMBER, P_SONG_ID_075 NUMBER, P_SONG_ID_076 NUMBER, P_SONG_ID_077 NUMBER, P_SONG_ID_078 NUMBER, P_SONG_ID_079 NUMBER, P_SONG_ID_080 NUMBER,
                   P_SONG_ID_081 NUMBER, P_SONG_ID_082 NUMBER, P_SONG_ID_083 NUMBER, P_SONG_ID_084 NUMBER, P_SONG_ID_085 NUMBER, P_SONG_ID_086 NUMBER, P_SONG_ID_087 NUMBER, P_SONG_ID_088 NUMBER, P_SONG_ID_089 NUMBER, P_SONG_ID_090 NUMBER,
                   P_SONG_ID_091 NUMBER, P_SONG_ID_092 NUMBER, P_SONG_ID_093 NUMBER, P_SONG_ID_094 NUMBER, P_SONG_ID_095 NUMBER, P_SONG_ID_096 NUMBER, P_SONG_ID_097 NUMBER, P_SONG_ID_098 NUMBER, P_SONG_ID_099 NUMBER, P_SONG_ID_100 NUMBER
         IS
         select
         from PRICE_DATA@PRICING_DB
         where COUNTRY = 'USA'
         and START_DATE <= sysdate
         and END_DATE > sysdate
         and vpc.SONG_ID IN
                   P_SONG_ID_001 ,P_SONG_ID_002 ,P_SONG_ID_003 ,P_SONG_ID_004 ,P_SONG_ID_005 ,P_SONG_ID_006 ,P_SONG_ID_007 ,P_SONG_ID_008 ,P_SONG_ID_009 ,P_SONG_ID_010,
                   P_SONG_ID_011 ,P_SONG_ID_012 ,P_SONG_ID_013 ,P_SONG_ID_014 ,P_SONG_ID_015 ,P_SONG_ID_016 ,P_SONG_ID_017 ,P_SONG_ID_018 ,P_SONG_ID_019 ,P_SONG_ID_020,
                   P_SONG_ID_021 ,P_SONG_ID_022 ,P_SONG_ID_023 ,P_SONG_ID_024 ,P_SONG_ID_025 ,P_SONG_ID_026 ,P_SONG_ID_027 ,P_SONG_ID_028 ,P_SONG_ID_029 ,P_SONG_ID_030,
                   P_SONG_ID_031 ,P_SONG_ID_032 ,P_SONG_ID_033 ,P_SONG_ID_034 ,P_SONG_ID_035 ,P_SONG_ID_036 ,P_SONG_ID_037 ,P_SONG_ID_038 ,P_SONG_ID_039 ,P_SONG_ID_040,
                   P_SONG_ID_041 ,P_SONG_ID_042 ,P_SONG_ID_043 ,P_SONG_ID_044 ,P_SONG_ID_045 ,P_SONG_ID_046 ,P_SONG_ID_047 ,P_SONG_ID_048 ,P_SONG_ID_049 ,P_SONG_ID_050,
                   P_SONG_ID_051 ,P_SONG_ID_052 ,P_SONG_ID_053 ,P_SONG_ID_054 ,P_SONG_ID_055 ,P_SONG_ID_056 ,P_SONG_ID_057 ,P_SONG_ID_058 ,P_SONG_ID_059 ,P_SONG_ID_060,
                   P_SONG_ID_061 ,P_SONG_ID_062 ,P_SONG_ID_063 ,P_SONG_ID_064 ,P_SONG_ID_065 ,P_SONG_ID_066 ,P_SONG_ID_067 ,P_SONG_ID_068 ,P_SONG_ID_069 ,P_SONG_ID_070,
                   P_SONG_ID_071 ,P_SONG_ID_072 ,P_SONG_ID_073 ,P_SONG_ID_074 ,P_SONG_ID_075 ,P_SONG_ID_076 ,P_SONG_ID_077 ,P_SONG_ID_078 ,P_SONG_ID_079 ,P_SONG_ID_080,
                   P_SONG_ID_081 ,P_SONG_ID_082 ,P_SONG_ID_083 ,P_SONG_ID_084 ,P_SONG_ID_085 ,P_SONG_ID_086 ,P_SONG_ID_087 ,P_SONG_ID_088 ,P_SONG_ID_089 ,P_SONG_ID_090,
                   P_SONG_ID_091 ,P_SONG_ID_092 ,P_SONG_ID_093 ,P_SONG_ID_094 ,P_SONG_ID_095 ,P_SONG_ID_096 ,P_SONG_ID_097 ,P_SONG_ID_098 ,P_SONG_ID_099 ,P_SONG_ID_100
         group by
               vpc.SONG_ID
              ,vpc.STOREFRONT_ID
         TYPE SONG_ID_TYPE IS TABLE OF MUSIC@MUSIC_DB%TYPE INDEX BY BINARY_INTEGER;
         V_SONG_ID_ARRAY                         SONG_ID_TYPE                     ;
         v_commit_counter           NUMBER := 0;
    BEGIN
         /* open cursor you intent to bulk collect from */
         OPEN C_CURRENT_MUSIC;
         LOOP
              /* in batches of 100, bulk collect ADAM_ID mapped TMS_IDENTIFIER into PLSQL table or records */
              FETCH C_CURRENT_MUSIC BULK COLLECT INTO V_SONG_ID_ARRAY LIMIT 100;
                   EXIT WHEN V_SONG_ID_ARRAY.COUNT = 0;
                   /* to avoid NO DATA FOUND error when pass 100 parameters to OPEN cursor, if the arrary
                      is not fully populated to 100, pad the array with nulls to fill up to 100 cells. */
                   IF (V_SONG_ID_ARRAY.COUNT >=1 and V_SONG_ID_ARRAY.COUNT <> 100) THEN
                        FOR j IN V_SONG_ID_ARRAY.COUNT+1..100 LOOP
                             V_SONG_ID_ARRAY(j) := null;
                        END LOOP;
                   END IF;
              /* pass a batch of 100 to cursor that get price information per SONG_ID and STOREFRONT_ID */
              FOR j IN C_get_music_price_data
                        V_SONG_ID_ARRAY(1) ,V_SONG_ID_ARRAY(2) ,V_SONG_ID_ARRAY(3) ,V_SONG_ID_ARRAY(4) ,V_SONG_ID_ARRAY(5) ,V_SONG_ID_ARRAY(6) ,V_SONG_ID_ARRAY(7) ,V_SONG_ID_ARRAY(8) ,V_SONG_ID_ARRAY(9) ,V_SONG_ID_ARRAY(10) ,
                        V_SONG_ID_ARRAY(11) ,V_SONG_ID_ARRAY(12) ,V_SONG_ID_ARRAY(13) ,V_SONG_ID_ARRAY(14) ,V_SONG_ID_ARRAY(15) ,V_SONG_ID_ARRAY(16) ,V_SONG_ID_ARRAY(17) ,V_SONG_ID_ARRAY(18) ,V_SONG_ID_ARRAY(19) ,V_SONG_ID_ARRAY(20) ,
                        V_SONG_ID_ARRAY(21) ,V_SONG_ID_ARRAY(22) ,V_SONG_ID_ARRAY(23) ,V_SONG_ID_ARRAY(24) ,V_SONG_ID_ARRAY(25) ,V_SONG_ID_ARRAY(26) ,V_SONG_ID_ARRAY(27) ,V_SONG_ID_ARRAY(28) ,V_SONG_ID_ARRAY(29) ,V_SONG_ID_ARRAY(30) ,
                        V_SONG_ID_ARRAY(31) ,V_SONG_ID_ARRAY(32) ,V_SONG_ID_ARRAY(33) ,V_SONG_ID_ARRAY(34) ,V_SONG_ID_ARRAY(35) ,V_SONG_ID_ARRAY(36) ,V_SONG_ID_ARRAY(37) ,V_SONG_ID_ARRAY(38) ,V_SONG_ID_ARRAY(39) ,V_SONG_ID_ARRAY(40) ,
                        V_SONG_ID_ARRAY(41) ,V_SONG_ID_ARRAY(42) ,V_SONG_ID_ARRAY(43) ,V_SONG_ID_ARRAY(44) ,V_SONG_ID_ARRAY(45) ,V_SONG_ID_ARRAY(46) ,V_SONG_ID_ARRAY(47) ,V_SONG_ID_ARRAY(48) ,V_SONG_ID_ARRAY(49) ,V_SONG_ID_ARRAY(50) ,
                        V_SONG_ID_ARRAY(51) ,V_SONG_ID_ARRAY(52) ,V_SONG_ID_ARRAY(53) ,V_SONG_ID_ARRAY(54) ,V_SONG_ID_ARRAY(55) ,V_SONG_ID_ARRAY(56) ,V_SONG_ID_ARRAY(57) ,V_SONG_ID_ARRAY(58) ,V_SONG_ID_ARRAY(59) ,V_SONG_ID_ARRAY(60) ,
                        V_SONG_ID_ARRAY(61) ,V_SONG_ID_ARRAY(62) ,V_SONG_ID_ARRAY(63) ,V_SONG_ID_ARRAY(64) ,V_SONG_ID_ARRAY(65) ,V_SONG_ID_ARRAY(66) ,V_SONG_ID_ARRAY(67) ,V_SONG_ID_ARRAY(68) ,V_SONG_ID_ARRAY(69) ,V_SONG_ID_ARRAY(70) ,
                        V_SONG_ID_ARRAY(71) ,V_SONG_ID_ARRAY(72) ,V_SONG_ID_ARRAY(73) ,V_SONG_ID_ARRAY(74) ,V_SONG_ID_ARRAY(75) ,V_SONG_ID_ARRAY(76) ,V_SONG_ID_ARRAY(77) ,V_SONG_ID_ARRAY(78) ,V_SONG_ID_ARRAY(79) ,V_SONG_ID_ARRAY(80) ,
                        V_SONG_ID_ARRAY(81) ,V_SONG_ID_ARRAY(82) ,V_SONG_ID_ARRAY(83) ,V_SONG_ID_ARRAY(84) ,V_SONG_ID_ARRAY(85) ,V_SONG_ID_ARRAY(86) ,V_SONG_ID_ARRAY(87) ,V_SONG_ID_ARRAY(88) ,V_SONG_ID_ARRAY(89) ,V_SONG_ID_ARRAY(90) ,
                        V_SONG_ID_ARRAY(91) ,V_SONG_ID_ARRAY(92) ,V_SONG_ID_ARRAY(93) ,V_SONG_ID_ARRAY(94) ,V_SONG_ID_ARRAY(95) ,V_SONG_ID_ARRAY(96) ,V_SONG_ID_ARRAY(97) ,V_SONG_ID_ARRAY(98) ,V_SONG_ID_ARRAY(99) ,V_SONG_ID_ARRAY(100)        
              LOOP
                   /* do stuff with data from Song and Pricing Database coming from the two
                        separate cursors, then continue processing more rows...
              END LOOP;
              /* commit after each batch of 100 SONG_IDs is processed */        
              COMMIT;
              EXIT WHEN C_CURRENT_MUSIC%NOTFOUND;  -- exit when there are no more rows to fetch from cursor
         END LOOP; -- bulk fetching loop
         CLOSE C_CURRENT_MUSIC; -- close cursor that was used in bulk collection
         /* commit rows */
         COMMIT; -- commit any remaining uncommitted data.
    END;

    I've got a problem when using passing VARRAY of numbers as parameter to remote cursor: it takes a super long time to run, sometimes doesn't finish even after an hour as passed.
    Continuing with my example in original entry, I replaced the bulk collect into PLSQL table collection with a VARRAY and i bulk collect into the VARRAY, this is fast and I know it works because I can DBMS_OUTPUT.PUT_LINE cells of VARRAY so I know it is getting populated correctly.  However, when I pass the VARRAY containing 100 cells populated with SONG_IDs as parameter to cursor, execution time is over an hour and when I am expecting a few seconds.
    Below code example strips the problem down to it's raw details, I skip the bulk collect and just manually populate a VARRAY with 100 SONG_ID values, then try to pass to as parameter to a cursor, but the execution time of cursor is unexpectedly long, over 30 minutes, sometime longer, when I am expecting seconds.
    IMPORTANT: If I take the same 100 SONG_IDs and place them directly in the cursor query's where IN clause, the SQL runs in under 5 seconds and returns result.  Also, if I pass the 100 SONG_IDs as individual cells of a PLSQL table collection, then it also runs fast.
    I thought that since the VARRAY is used via select subquery that is it queried locally, but the cursor is remote, and that I had a distribute problem on my hands, so I put in the DRIVING_SITE hint to attempt to force the result of query against VARRAY to go to remote server and rest of query will run there before returning result, but that didn't work either, still got slow response.
    Is something wrong with my code, or I am running into a Oracle problem that may require support to resolve?
    DECLARE
         /*  define a parameterized cursor that accepts XXX number of in SONG_IDs and
          retrieves required pricing information
         CURSOR C_get_music_price_data
      p_array_song_ids SYS.ODCInumberList              
         IS
         select  /*+DRIVING_SITE(pd) */
      count(distinct s.EVE_ID)
         from PRICE_DATA@PRICING_DB pd
         where pd.COUNTRY = 'USA'
         and pd.START_DATE <= sysdate
         and pd.END_DATE > sysdate
         and pd.SONG_ID IN
              select column_value from table(p_array_song_ids)
         group by
               pd.SONG_ID
              ,pd.STOREFRONT_ID
      V_ARRAY_SONG_IDS SYS.ODCInumberList := SYS.ODCInumberList();    
    BEGIN
    V_ARRAY_SONG_IDS.EXTEND(100);
    V_ARRAY_SONG_IDS(  1 ) := 31135  ;
    V_ARRAY_SONG_IDS(  2 ) := 31140   ;
    V_ARRAY_SONG_IDS(  3 ) := 31142   ;
    V_ARRAY_SONG_IDS(  4 ) := 31144   ;
    V_ARRAY_SONG_IDS(  5 ) := 31146   ;
    V_ARRAY_SONG_IDS(  6 ) := 31148   ;
    V_ARRAY_SONG_IDS(  7 ) := 31150   ;
    V_ARRAY_SONG_IDS(  8 ) := 31152   ;
    V_ARRAY_SONG_IDS(  9 ) := 31154   ;
    V_ARRAY_SONG_IDS( 10 ) := 31156   ;
    V_ARRAY_SONG_IDS( 11 ) := 31158   ;
    V_ARRAY_SONG_IDS( 12 ) := 31160   ;
    V_ARRAY_SONG_IDS( 13 ) := 33598   ;
    V_ARRAY_SONG_IDS( 14 ) := 33603   ;
    V_ARRAY_SONG_IDS( 15 ) := 33605   ;
    V_ARRAY_SONG_IDS( 16 ) := 33607   ;
    V_ARRAY_SONG_IDS( 17 ) := 33609   ;
    V_ARRAY_SONG_IDS( 18 ) := 33611   ;
    V_ARRAY_SONG_IDS( 19 ) := 33613   ;
    V_ARRAY_SONG_IDS( 20 ) := 33615   ;
    V_ARRAY_SONG_IDS( 21 ) := 33617   ;
    V_ARRAY_SONG_IDS( 22 ) := 33630   ;
    V_ARRAY_SONG_IDS( 23 ) := 33632   ;
    V_ARRAY_SONG_IDS( 24 ) := 33636   ;
    V_ARRAY_SONG_IDS( 25 ) := 33638   ;
    V_ARRAY_SONG_IDS( 26 ) := 33640   ;
    V_ARRAY_SONG_IDS( 27 ) := 33642   ;
    V_ARRAY_SONG_IDS( 28 ) := 33644   ;
    V_ARRAY_SONG_IDS( 29 ) := 33646   ;
    V_ARRAY_SONG_IDS( 30 ) := 33648   ;
    V_ARRAY_SONG_IDS( 31 ) := 33662   ;
    V_ARRAY_SONG_IDS( 32 ) := 33667   ;
    V_ARRAY_SONG_IDS( 33 ) := 33669   ;
    V_ARRAY_SONG_IDS( 34 ) := 33671   ;
    V_ARRAY_SONG_IDS( 35 ) := 33673   ;
    V_ARRAY_SONG_IDS( 36 ) := 33675   ;
    V_ARRAY_SONG_IDS( 37 ) := 33677   ;
    V_ARRAY_SONG_IDS( 38 ) := 33679   ;
    V_ARRAY_SONG_IDS( 39 ) := 33681   ;
    V_ARRAY_SONG_IDS( 40 ) := 33683   ;
    V_ARRAY_SONG_IDS( 41 ) := 33685   ;
    V_ARRAY_SONG_IDS( 42 ) := 33700   ;
    V_ARRAY_SONG_IDS( 43 ) := 33702   ;
    V_ARRAY_SONG_IDS( 44 ) := 33704   ;
    V_ARRAY_SONG_IDS( 45 ) := 33706   ;
    V_ARRAY_SONG_IDS( 46 ) := 33708   ;
    V_ARRAY_SONG_IDS( 47 ) := 33710   ;
    V_ARRAY_SONG_IDS( 48 ) := 33712   ;
    V_ARRAY_SONG_IDS( 49 ) := 33723   ;
    V_ARRAY_SONG_IDS( 50 ) := 33725   ;
    V_ARRAY_SONG_IDS( 51 ) := 33727   ;
    V_ARRAY_SONG_IDS( 52 ) := 33729   ;
    V_ARRAY_SONG_IDS( 53 ) := 33731   ;
    V_ARRAY_SONG_IDS( 54 ) := 33733   ;
    V_ARRAY_SONG_IDS( 55 ) := 33735   ;
    V_ARRAY_SONG_IDS( 56 ) := 33737   ;
    V_ARRAY_SONG_IDS( 57 ) := 33749   ;
    V_ARRAY_SONG_IDS( 58 ) := 33751   ;
    V_ARRAY_SONG_IDS( 59 ) := 33753   ;
    V_ARRAY_SONG_IDS( 60 ) := 33755   ;
    V_ARRAY_SONG_IDS( 61 ) := 33757   ;
    V_ARRAY_SONG_IDS( 62 ) := 33759   ;
    V_ARRAY_SONG_IDS( 63 ) := 33761   ;
    V_ARRAY_SONG_IDS( 64 ) := 33763   ;
    V_ARRAY_SONG_IDS( 65 ) := 33775   ;
    V_ARRAY_SONG_IDS( 66 ) := 33777   ;
    V_ARRAY_SONG_IDS( 67 ) := 33779   ;
    V_ARRAY_SONG_IDS( 68 ) := 33781   ;
    V_ARRAY_SONG_IDS( 69 ) := 33783   ;
    V_ARRAY_SONG_IDS( 70 ) := 33785   ;
    V_ARRAY_SONG_IDS( 71 ) := 33787   ;
    V_ARRAY_SONG_IDS( 72 ) := 33789   ;
    V_ARRAY_SONG_IDS( 73 ) := 33791   ;
    V_ARRAY_SONG_IDS( 74 ) := 33793   ;
    V_ARRAY_SONG_IDS( 75 ) := 33807   ;
    V_ARRAY_SONG_IDS( 76 ) := 33809   ;
    V_ARRAY_SONG_IDS( 77 ) := 33811   ;
    V_ARRAY_SONG_IDS( 78 ) := 33813   ;
    V_ARRAY_SONG_IDS( 79 ) := 33815   ;
    V_ARRAY_SONG_IDS( 80 ) := 33817   ;
    V_ARRAY_SONG_IDS( 81 ) := 33819   ;
    V_ARRAY_SONG_IDS( 82 ) := 33821   ;
    V_ARRAY_SONG_IDS( 83 ) := 33823   ;
    V_ARRAY_SONG_IDS( 84 ) := 33825   ;
    V_ARRAY_SONG_IDS( 85 ) := 33839   ;
    V_ARRAY_SONG_IDS( 86 ) := 33844   ;
    V_ARRAY_SONG_IDS( 87 ) := 33846   ;
    V_ARRAY_SONG_IDS( 88 ) := 33848   ;
    V_ARRAY_SONG_IDS( 89 ) := 33850   ;
    V_ARRAY_SONG_IDS( 90 ) := 33852   ;
    V_ARRAY_SONG_IDS( 91 ) := 33854   ;
    V_ARRAY_SONG_IDS( 92 ) := 33856   ;
    V_ARRAY_SONG_IDS( 93 ) := 33858   ;
    V_ARRAY_SONG_IDS( 94 ) := 33860   ;
    V_ARRAY_SONG_IDS( 95 ) := 33874   ;
    V_ARRAY_SONG_IDS( 96 ) := 33879   ;
    V_ARRAY_SONG_IDS( 97 ) := 33881   ;
    V_ARRAY_SONG_IDS( 98 ) := 33883   ;
    V_ARRAY_SONG_IDS( 99 ) := 33885   ;
    V_ARRAY_SONG_IDS(100 ) := 33889  ;
        /* do stuff with data from Song and Pricing Database coming from the two
      separate cursors, then continue processing more rows...
      FOR i IN C_get_music_price_data( v_array_song_ids ) LOOP
      . (this is the loop where I pass in v_array_song_ids
      .  populated with only 100 cells and it runs forever)
      END LOOP; 
    END;

  • Use of IN function with parameters?

    is it possible to use a parameter with an IN function, inside an explicit cursor?
    oracle doesn't accept varchars or collections.
    it should be something like this:
    CURSOR (myParam VARCHAR2) IS
    SELECT *
    FROM myTable
    WHERE myColumn IN (myParam);
    Thank you!
    Saverio M.

    Sorry just one correction
    Do you mean Parameterized Cursors ?
    declare
    v_emp number;
    v_emp1 number;
    cursor c1(v_emp in number)
    is
    select * from empdept where empno=v_emp;
    begin
    v_emp1 :=9939; -- For Example you
    for x in c1(v_emp1)
    loop
    --- Do your processes.
    null;
    end loop;
    end;
         | Legal | Privacy

  • Dynamic Spatial Cursor?

    I have a working cursor which selects and operates on some spatial data.
    The cursor uses the GETVERTICES spatial function.
    The current query works only for geom_id = 347.
    I need to iterate through all the geometries in the database i.e. repeat the query for geom_id = 1. geom_id = 2 ... etcetera.
    Given that a cursor is defined in the declaration section, how can I dynamically change the geom_id and rerun the query for all geometries?
    declare
    ...stuff
    cursor c1 is
    SELECT t.X, t.Y, ne_id
    FROM SDO_TABLE c,
    TABLE(SDO_UTIL.GETVERTICES(c.geom)) t
    where geom_id = 347;
    begin
    open c1;
    fetch ...stuff
    loop
    ...do stuff with fetched data
    end loop;
    close c1;
    end;

    Hi,
    I hope the below parameterized cursor will help you:
    DECLARE
    CURSOR c1(p_num NUMBER )
    IS
    SELECT * FROM A
    WHERE Rd = p_num;
    R1 c1%ROWTYPE;
    BEGIN
    -- fetch genom number from other cursor OR if its static calue then call the above cursor as many times
    OPEN c1(200);
    LOOP
    FETCH c1 INTO r1;
    EXIT WHEN c1%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(r1.sd );
    END LOOP;
    END;
    ~Vinod

  • Cursor in cursor?

    create or notcreate procedure as
    cursor s1 is (select * from sellers);
    cursor s2 is (select * from orders where seller_id=s1.seller_id);
    begin
    null;
    end;
    hi guys! can i do something like that?

    Hi,
    Not exactly.
    You can have a cursor that takes parameters:
    cursor s2 (p_id NUMBER)
    is  select  *
        from    orders
        where   seller_id = p_id
    );You pass the parameters when you open the cursor, e.g.
    OPEN  s2 (s1.seller_id);Often, the only reason for doing nested cursors is that you can't figure out how to do it in one cursor.
    Explain what you're trying to do, and perhaps someone will show you an easier, more efficient way to do it.

  • Ref Cursor - how to access through parameter name

    Hi,
    I'm using the below table and sample data. The below script named 'Script1' works well, my concern is values for the first and second parameters need to be used for the thrid and fourth one as well.
    When I try with 'Script2' it gives "ORA-01008: not all variables bound ORA-06512: at line 17" error. I know Paramterized cursor can handle this effecively, since it is a dynamic SQL, I need to use from a parameter table, I don't have any control over the number of parameteters, parameter name, type and other things. So, I cannot go for parameterized cursor.
    As of now, for my requirement, Script1 works fine, is there any way to make Script2 to work as well, I need to pass paramters by name, not by position, please give your suggestions, thank you.
    CREATE TABLE T1
    F1 NUMBER(5),
    F2 VARCHAR2(100),
    F3 DATE
    Insert into T1
    (F1, F2, F3)
    Values
    (1, 'One', TO_DATE('08/02/2012 07:43:34', 'MM/DD/YYYY HH24:MI:SS'));
    Insert into T1
    (F1, F2, F3)
    Values
    (2, 'Two', TO_DATE('08/02/2012 08:15:24', 'MM/DD/YYYY HH24:MI:SS'));
    Insert into T1
    (F1, F2, F3)
    Values
    (3, 'Three', TO_DATE('08/02/2012 08:16:34', 'MM/DD/YYYY HH24:MI:SS'));
    COMMIT;
    Script1:
    declare
    TYPE t_ref_cursor IS REF CURSOR;
    v_cursor t_ref_cursor;
    v_query_str varchar2(3000);
    v_f1 number(5);
    v_f2 varchar2(100);
    v_f3 date;
    begin
    v_query_str := 'SELECT f1, f2, f3 from t1 where f1 = :p1 and f3 = to_date(:p2, ''DD-MON-YYYY hh24:mi:ss'') union ';
    v_query_str := v_query_str || 'select 1, ''c1'', sysdate from dual where not exists (select 1 from t1 where f1 = :p3 and f3 = to_date(:p4, ''DD-MON-YYYY hh24:mi:ss''))';
    --dbms_output.put_line(v_query_str);
    open v_cursor for v_query_str using 1, '02-AUG-2012 07:43:34', 1, '02-AUG-2012 07:43:34';
    loop
    fetch v_cursor into v_f1, v_f2, v_f3;
    exit when v_cursor%notfound;
    dbms_output.put_line(v_f1 || ' ' || v_f2 || '' || v_f3);
    end loop;
    dbms_output.put_line('rowcount ' || v_cursor%rowcount);
    close v_cursor;
    end;
    Script2:
    declare
    TYPE t_ref_cursor IS REF CURSOR;
    v_cursor t_ref_cursor;
    v_query_str varchar2(3000);
    v_f1 number(5);
    v_f2 varchar2(100);
    v_f3 date;
    begin
    v_query_str := 'SELECT f1, f2, f3 from t1 where f1 = :p1 and f3 = to_date(:p2, ''DD-MON-YYYY hh24:mi:ss'') union ';
    v_query_str := v_query_str || 'select 1, ''c1'', sysdate from dual where not exists (select 1 from t1 where f1 = :p1 and f3 = to_date(:p2, ''DD-MON-YYYY hh24:mi:ss''))';
    --dbms_output.put_line(v_query_str);
    open v_cursor for v_query_str using 1, '02-AUG-2012 07:43:34';
    loop
    fetch v_cursor into v_f1, v_f2, v_f3;
    exit when v_cursor%notfound;
    dbms_output.put_line(v_f1 || ' ' || v_f2 || '' || v_f3);
    end loop;
    dbms_output.put_line('rowcount ' || v_cursor%rowcount);
    close v_cursor;
    end;
    /

    This link shall answer your Question. PL/SQL Dynamic SQL.
    If it had been an Anonymous Block, your code would work through.
    Please see demonstration below:
    create or replace procedure emp_data (dep_id    number, sal   number, emp_id    number)
    is
      l_cnt   number;
    begin
      select count(*)
        into l_cnt
        from hr.employees
       where department_id = dep_id
         and salary >= sal
         and employee_id > emp_id;
      dbms_output.put_line('Count :: ' || l_cnt);
    end;
    declare
      l_cnt           number;
    begin
      execute immediate 'begin emp_data(:1, :2, :2); end;' using 20, 100;
    end;
    anonymous block completed
    Count :: 2
    --Trying the Similar example as in your OP.
    --Execute the same Select statement as in emp_Data with Bind Variables;
    declare
      l_cnt           number;
    begin
      --execute immediate 'begin emp_data(:1, :2, :2); end;' using 20, 100;
      execute immediate 'select count(*)
        from hr.employees
       where department_id = :1
         and salary >= :2
         and employee_id > :2' into l_cnt using 20, 100;
      dbms_output.put_line('Count :: ' || l_cnt);
    end;
    Results in error :- ORA-01008: not all variables bound

  • A newbie for cursors...

    Hello,
    I have a parameterized cursor that i have successfully opened. However, i wish to return it via the calling procedure's poResult out sys_refcursor .
    any ideas please?
    Thanks in advance
    Alan Seunarayan

    Have a look at Tom Kytes detailed HowTo
    Getting Result Sets from Stored Procedures
    http://asktom.oracle.com/~tkyte/ResultSets/index.html

  • Strange cursor problem (Star Trek themed db!)

    Hi,
    I have below a set of tables, and the code I'm running. The first half of the code does exactly what I want it to do. But I am trying to take those results and pull more information out of them, as noted below using %FOUND
    DECLARE
    CURSOR planet_cursor IS
         SELECT planet_num, planet_name
         FROM planet;     
    v_pnumb   planet.planet_num%TYPE;
    v_pname    planet.planet_name%TYPE;
    v_snum    starbase.star_num%TYPE;
    v_bname   starbase.base_name%TYPE;
    v_basePnum  starbase.planet_num%TYPE;
    BEGIN
    OPEN planet_cursor;
    LOOP
         FETCH planet_cursor INTO v_pnumb, v_pname;
         dbms_output.put_line('My number is ' || v_pnumb || ' and my name is ' || v_pname);
         EXIT WHEN planet_cursor%NOTFOUND;
    END LOOP;     
    -- *the above explicit cursor works correctly. However, I want to count the number of bases on each star While that FETCH is taking place*
    --* First, I am just testing to see if I can even pull out the number of bases from each star using an implicit cursor (one result out of the set of previous results)*
    WHILE planet_cursor%FOUND
    LOOP
    SELECT COUNT(starbase.planet_num)
         INTO v_basePnum
         FROM starbase
         WHERE vbasePnum = v_snum;
         dbms_output.put_line('I have ' || v_basePnum || 'number of bases');
    END LOOP;
    CLOSE planet_cursor;
    END;I just want to Count the number of bases on each planet using an implicit cursor select statement to sort of weed through the explicit cursor results.
    Tables
    CREATE TABLE planet
    (planet_num VARCHAR2(3),
    planet_name VARCHAR2(20));
    CREATE TABLE starbase
    (star_num VARCHAR2(2),
    base_name VARCHAR2(20),
    planet_num VARCHAR2(3));
    INSERT INTO planet VALUES
    (257, 'Neptune');
    INSERT INTO planet VALUES
    (367, 'Venus');
    INSERT INTO planet VALUES
    (586, 'Mars');
    INSERT INTO planet VALUES
    (725, 'Earth');
    INSERT INTO starbase VALUES
    (01, 'Neptune Base', 257);
    INSERT INTO starbase VALUES
    (02, 'Venus Base', 367);
    INSERT INTO starbase VALUES
    (03, 'Mars Base', 586);
    INSERT INTO starbase VALUES
    (04, 'Mars Base 2', 586);
    INSERT INTO starbase VALUES
    (05, 'Mars Base 3', 586);
    INSERT INTO starbase VALUES
    (06, 'Mars Base 4', 586);
    INSERT INTO starbase VALUES
    (07, 'Earth Base', 725);
    INSERT INTO starbase VALUES
    (08, 'Earth Base 2', 725);Edited by: user8998591 on Mar 26, 2010 2:21 PM
    Edited by: user8998591 on Mar 26, 2010 2:22 PM
    Edited by: user8998591 on Mar 27, 2010 12:46 PM

    user8998591 wrote:
    Thank you for the helpful feedback. You both have really helped expose a lot of what I was doing wrong.
    I have recreated the problem in a slightly different scenario to demonstrate again what I am trying to do. My goal is to indeed use block pl/sql, and to be able to use a while loop to pull data from the initial cursor. That is the whole idea. I know there are other ways of doing this, but this is exactly what I am trying to do. I have been narrowing down, further and further, how to create the program. At this point I am really not sure if I only need to tweak a few things, or start from the ground up. Are you saying that the whole point of this is to learn how to use cursors, nested cursors in particular?
    An important part of learning about cursors (or anything else) is learning when it is appropriate to use them. Bhushan and I have both posted PL/SQL code that gets the results you want using one cursor. It's rare when you need a nested cursor, and this problem is not one of those rare cases. Using a second cursor here is silly and inefficient. You should not be practicing how to do silly and inefficient things. There are lots of sensible things to do, and efficient ways to do them: you should spend your time learning and practicing sensible, efficient things.
    As you can see, I created and fetched planet_cursor. I then want to use a While loop to select the number of bases on each planet. This is what I have been fighting with. Again and again but this is exactly what I am trying to do. If you really, really must do this, then define another cursor, similar to the one you already have for the planets, and use that cursor just like you use the one for the planets: that is:
    (1) OPEN the cursor
    (2) Start a LOOP
    (3) FETCH the cursor
    (4) EXIT WHEN ...%NOTFOUND
    (5) within the LOOP, do whatever you need to do with the data. (There's no need to explicitly say WHEN ...%FOUND; the code that follows EXIT WHEN ....%NOTFOUND will only be done when a row was found.)
    (6) END LOOP
    (7) CLOSE the cursor
    The question in your mind seems to be: Where do I do all this?
    This is something that you want to do for each planet. That is, every time you find a different planet, you will want to run the base_cursor. So put it inside the LOOP for the planet_cursor, where it will be done over and over, as many times as there are planets:
    DECLARE
         CURSOR planet_cursor IS
               SELECT  p_name
               ,           p_id
                      FROM    planet;
         CURSOR base_cursor (this_p_id  IN  star_base.p_id%TYPE) IS
               SELECT  b_id
               ,           b_name
               FROM    star_base
               WHERE   p_id     = this_p_id;
         planet_name   planet.p_name%TYPE;
         planet_id     planet.p_id%TYPE;
         base_id       star_base.b_id%TYPE;
         base_name     star_base.b_name%TYPE;
         base_cnt      PLS_INTEGER;
    BEGIN
           OPEN planet_cursor;
           LOOP     -- to fetch planets
               FETCH planet_cursor INTO planet_name, planet_id;
            EXIT WHEN planet_cursor%NOTFOUND;
            base_cnt := 0;
            OPEN base_cursor (planet_id);
            LOOP              -- To fetch bases
                FETCH base_cursor INTO base_id, base_name;
                EXIT WHEN  base_cursor%NOTFOUND;
                base_cnt := base_cnt + 1;     
            END LOOP;         -- to fetch bases
            CLOSE  base_cursor;
               dbms_output.put_line('Planet ' || planet_name ||  ' has ' || base_cnt || ' star base(s)');
        END LOOP;     -- to fetch planets
        CLOSE planet_cursor;
    END;
    /Notice that this uses a parameterized cursor: base_cursor is defined to take an argument, very much like a procedure or function is defined to take an argument, and, when you open the cursor, you specify a value for that argument, very much like you pass argument values when you call a procedure or function.
    Below is another example of my code, and a different table to demonstrate my problem. I also included my expected output. Any assistance will be rewarded with a base station named after them when I am done completing this database :) Thanks for posting the code and the sample data.
    Why did you double-space them? The PL/SQL is hard to read that way, and I had to manually edit the INSERT statements to get rid of the blank lines.
    In case anyone else want to run them, here they are:
    INSERT INTO PLANET VALUES
    (1, 'Adigeon Prime');
    INSERT INTO PLANET VALUES
    (2, 'Borg Prime');
    INSERT INTO PLANET VALUES
    (3, 'Meles II');
    INSERT INTO PLANET VALUES
    (4, 'Prometheus');
    INSERT INTO PLANET VALUES
    (5, 'Turkana IV');
    INSERT INTO STAR_BASE VALUES
    (1, 'Tiberius', 1);
    INSERT INTO STAR_BASE VALUES
    (2, 'Spock', 2);
    INSERT INTO STAR_BASE VALUES
    (3, 'Bones', 1);
    INSERT INTO STAR_BASE VALUES
    (4, 'Sulu', 3);
    INSERT INTO STAR_BASE VALUES
    (5, 'Uhura', 4);Try to give your variables names that reflect what they contain.
    Kirk_id is a great name for a variable, but it's a terrible name for a variable that contains the total number of star bases.

  • Help on Cursors

    Hi,
    I am having the following cursor, which returns 10000 rows.
    Cursor c1 is
    select * from emp;
    I have the following query on the above cursor.
    1) Is there any way by which I can directly go to the 1000th row.
    2) Since the above cursor has an Emp_Name column, is there any way by which I can directly go to the row having an Emp_Name='Whatever'.
    Thanking you in advance for your kind help.
    MAK

    for the second point you can simple add the where condition in the cursor query, like:
    CURSOR c1 IS
    SELECT * FROM emp WHERE emp_name = 'Whatever';
    if your value is static you can do it this way, else you can write a parameterized cursor as follows:
    CURSOR c1(pEmpName VARCHAR2) IS
    SELECT * FROM emp WHERE emp_name = pEmpName;
    and then open the cursor like this:
    OPEN c1('Whatever');
    for the first point, going directly to 1000th row, as far as i know, you have to navigate thru the loop.

  • What is wrong in the pl/sql block

    Hi, I am unable to pass the parameter of one cursor to other cursor.
    create table temp3 as select * from dept;
    create table temp4 as select * from emp;
    create or replace procedure xx_rep is
    cursor xx_dep_cur is select deptno from dept;
    cursor xx_emp_cur(p_dept number)
    is  select sal,comm from temp4 where deptno =p_dept;
       TYPE idt_cur_dep2 IS TABLE OF xx_dep_cur%ROWTYPE
                  INDEX BY PLS_INTEGER;
           t_idt_cur_dep2       idt_cur_dep2;
    TYPE idt_cur_emp2 IS TABLE OF xx_emp_cur(p_dept number)%ROWTYPE
                  INDEX BY PLS_INTEGER;
           t_idt_cur_emp2      idt_cur_emp2;
    BEGIN
    OPEN xx_dep_cur;
    LOOP
    FETCH xx_dep_cur
       BULK COLLECT INTO t_idt_cur_dep2 LIMIT 1000;
    EXIT WHEN t_idt_cur_dep2.count<=0;
    FOR indx in t_idt_cur_dep2.first .. t_idt_cur_dep2.last LOOP
    DELETE  from temp3 where deptno=t_idt_cur_dep2(indx).deptno;
    --main update
    BEGIN
    OPEN xx_emp_cur(t_idt_cur_dep2(indx).deptno);
    LOOP
    FETCH xx_emp_cur
       BULK COLLECT INTO t_idt_cur_emp2 LIMIT 1000;
    EXIT WHEN t_idt_cur_emp2.count<=0;
    FOR indx in t_idt_cur_emp2.first .. t_idt_cur_emp2.last LOOP
    UPDATE temp4 set
    comm=10 , sal =100  where deptno=t_idt_cur_dep2(indx).deptno;
    END LOOP;
    END LOOP;
    close xx_emp_cur(t_idt_cur_dep2(indx).deptno);
    EXCEPTION
            WHEN OTHERS
                THEN
                    dbms_output.put_line('Exception' || SQLCODE||' '|| SQLERRM);
          END;
    --end of main update
    END LOOP;
    END LOOP;
    COMMIT;
    Close xx_dep_cur;
    EXCEPTION
            WHEN OTHERS
                THEN
                     dbms_output.put_line('Exception'|| SQLCODE||' '|| SQLERRM);
          END;
        

    You have syntax errors and when you fix the couple I noticed you will find a few more.
    First place a
    show errors;
    at the end of your code. This will display your errors so you do not have to query user_errors. When you close a parameterized cursor you just use the cursor name without any parameters nor would the parameter list appear in the cursor reference in the Type statement on line 13.
    The rest is up to you.
    HTH -- Mark D Powell --

  • Calling from the application Slow vs. Running through SQL developer Fast

    Alright, we write many applications that make use of calling stored procedures in packages to return data. This is the only time i have ever encountered this issue and have not been able to pinpoint the cause.
    This application is very data-centric and is filled with calls to stored procedures and I would say about 80% run fine as in the time required to run is about the same as in SQL Developer maybe just a little slower due to the amount of data that may be returned to the application. The other 20% run horribly slow from the application and run lighting fast in SQL Developer and i cannot figure out why.
    I have traced the code right up to the .Fill on the Oracle.DataAccess.Client.OracleDataAdapter and that is where it just holds either for a long period of time or just forever, some of these i haved waited hours for and they have not finished running.
    For Example: I created a new page in the project and it makes a request through the use of ajax, when the request file is reached it performs two stored procedures from the same package (the only two procedures in the package). Both procedures take in three varchar2's and have an in out cursor, the cursor is returned into a datatable in the VB. The first query runs in a couple seconds returns the correct data etc. The second query, which takes .2 seconds on average to run from SQL Developer, just runs and runs and i have never actually even waited for it to finish because it takes so long. The specific example i am trying only returns 1 row with 7 columns, so there is not a large amount of data being passed back.
    I have seen this sort of thing happen on occasions, but everytime it was usually because the package was not compiled and was waiting on a view to finish before compilation and after killing the view it was fine. But this issue seems to happen randomnly with certain procedures and not others all in the same package.
    This issue happens on the same procedures everytime which would lead me to believe it is the procedure, but running them in SQL Developer shows me this is incorrect because they run exceptionally fast in some cases. I even went so far as to restart the entire database just in case there was some sort of lock causing this issue but this did not fix the issue.
    I have verified parameters, cursors, debugged the procedures, stepped every line of code, tried deleting and readding the oracle.dataAccess reference. I can't seem to figure this one out.
    It is causing alot of wasted time because i am forced to wait a horribly long time for these queries in order to test. If anyone has any clues, hints, or ideas as to what this could be please let me know! If the same issue exists when the application is moved into production it will be unnacceptable and the application utterly unusable.
    Thanks in Advance for any help!
    -Jarrod

    Hi,
    This is consistently reproducible with the problem procedure/operations? Total WAG here, but I've seen cases where having support for distributed transactions enabled causes the database to disable certain optimizations. Try setting Enlist=false in your connection string.
    Otherwise, I'd recommend enabling 10046 database trace and client side sqlnet trace to capture the problem behavior for further investigation. Oracle support can certainly give you a hand with that if needed.
    Hope it helps,
    Greg

Maybe you are looking for

  • Playing Visualizations on Secondary Monitor

    Hey guys, Do you know of any way to have the iTunes visualizations output on ONLY the secondary monitor. I would like to have a party and be able to change songs without the visuals cutting out on my LCD TV. Any help would be appreciated. -Brian

  • HT201304 Trying to do an game in app purchase and it won't let me.  When I do music no problem

    I can't get the in app purchase to work. Says see iTunes support.  I can do music no problem. Verified payment information and still no go. Thought it might be some kind of money cap but did one yesterday for same amt and it cleared no problem

  • Can't export Excel files

    In Discoverer Server - 10.1.2.48.18, I can't export Excel files. I already reed threads about macro security, regedit and regional languages but I still can't export xsl and cvs files. there is a patch or something to do ?? Thx

  • Copy Paste Images...Plz help..

    Hi All, I am trying to find solution to Select a part of the image in my Panel and paste it in the same panel where the user wishes to...We can do this using clipboard ,but this will be pasted on the panel as an image...but i want the co-ordinates of

  • SWFObject Scaling

    I'm using SWFObject and the function: so.addParam("scale", "showall"); What I want to do is autoscale to the window, but also set a max size for the site to avoid pixelation. Secondly, this scale command makes the size postage-stamp like in Firefox a