Process having dynamic subqery in for loop cursor

I created a process that puts all retrieved rows into a collection. Users can select on quite a few columns, say unit, last_name, shift, etc. When the query is built based on users' inputs, I can't get it working using a For Loop Cursor (code 3.). But I tried and found out that sample 1 is working while sample 2 is not.
Can anyone please help? give advices or point to the right direction?
Thanks very much in advance!!!
DC
sample 1, works:
begin
:P8_TEST_CURSOR := '';
for c in ( select ename from emp ) loop
:P8_TEST_CURSOR := :P8_TEST_CURSOR || ', ' || c.ename;
end loop;
end;
sample 2, does not work:
declare
q varchar2(2000) := 'select ename from emp';
begin
:P8_TEST_CURSOR := '';
for c in q loop
:P8_TEST_CURSOR := :P8_TEST_CURSOR || ', ' || c.ename;
end loop;
end;
code 3, my actually pursuing code, sorry it's long:
declare
q varchar2(2000);
v_unit_id cpd_units.id%TYPE;
begin
q := 'select distinct e.user_id
, nvl(to_char(law_common.get_star_no(e.id)), ''-'') star_no
, nvl(e.last_nme, ''-'') last_name
, nvl(e.first_nme, ''-'') first_name
, nvl(e.MIDDLE_INITIAL, ''-'') middle_initial
, e.employee_no
, nvl(to_char(e.employee_position_cd), ''-'')
, nvl(w.uod_cd, e.cpd_unit_assigned_no) unit
, nvl(w.watch_cd, ''-'')
from cpd_employees e, dpv2wtch w
where e.status_i = ''Y''
and nvl(e.resignation_date, sysdate) >= sysdate
and e.employee_position_cd in (''9112'', ''9152'', ''9153'', ''9155'', ''9161'', ''9164'')
and e.user_id is not null
and w.ssn_no(+) = e.ssn
and e.user_id not in (select c001
from htmldb_collections
where collection_name = ''ACTIVITY''
if :P300_STAR_NO is not NULL then
q := q || ' and e.id = law_common.get_employee_id(:P300_STAR_NO)';
--q := q || ' and law_common.get_star_no(e.id) = :P300_STAR_NO';
end if;
if :P300_EMPLOYEE_NO is not NULL then
q := q || ' and e.employee_no = :P300_EMPLOYEE_NO';
end if;
if :P300_USER_ID is not NULL then
q := q || ' and e.user_id = :P300_USER_ID';
end if;
if :P300_LAST_NAME is not NULL then
q := q || ' and upper(e.last_nme) like ''' || upper(:P300_LAST_NAME) || '%''';
end if;
if :P300_FIRST_NAME is not NULL then
q := q || ' and upper(e.first_nme) like ''' || upper(:P300_FIRST_NAME) || '%''';
end if;
if :P300_EMPLOYEE_POSITION_CD is not NULL then
q := q || ' and e.employee_position_cd = :P300_EMPLOYEE_POSITION_CD';
end if;
if :P300_UNIT is not NULL then
q := q || ' and nvl(w.uod_cd, e.cpd_unit_assigned_no) = :P300_UNIT';
end if;
if :P300_WATCH_CD <> 'NULL' then
q := q || ' and w.watch_cd = :P300_WATCH_CD';
end if;
--htp.p('Limit Unit '||:P0_LIMIT_UNIT);
/* authorization of editing OWN, UNIT, or ALL recs */
if substr(:P0_PERMISSION, 1, 5) = 'QUERY' then
q := q || ' and e.user_id = v(''FLOW_USER'')';
elsif substr(:P0_PERMISSION, -4, 4) = 'UNIT' then
q := q || ' and coalesce(w.uod_cd, e.cpd_unit_assigned_no)= :P0_LIMIT_UNIT ';
end if;
htp.p('q: ' || q);
cursor q_c is q;
for c in ( q_c ) loop /* HOW CAN BE DYNAMIC ???? */
l_seq_id := htmldb_collection.add_member(
p_collection_name => 'OFFICER_ACTIVITY'
, p_c001 => c.user_id
, p_c002 => c.star_no
, p_c003 => c.last_name
, p_c004 => c.first_name
, p_c005 => c.middle_initial
, p_c006 => c.employee_no
, p_c007 => c.employee_position_cd
, p_c008 => c.unit
, p_c009 => c.watch_cd
, p_c050 => :P0_APP_USER
end loop;
end;

Come back to solve my need. I get the working test process:
declare
type ty_cursor is ref cursor;
my_cursor ty_cursor;
my_rec emp%rowtype;
l_num number := 7900;
q varchar2(2000) ;
l_using varchar2(200) := null;
begin
:P8_TEST_CURSOR := '';
q := 'select * from emp';
if :P8_ENAME is not null then
q := q || ' where ename like :P8_ENAME';
l_using := ':P8_ENAME';
end if;
if l_using is not null then
open my_cursor for q using :P8_ENAME; --l_using;
else
open my_cursor for q;
end if;
loop
fetch my_cursor into my_rec;
exit when my_cursor%notfound;
:P8_TEST_CURSOR := :P8_TEST_CURSOR || ', ' || my_rec.empno;
end loop;
end;
But I need
open my_cursor for q using l_using;
to be working since my application has several searchable columns for users and I have to put users' input search into l_using. It does NOT work: q got 'select * from emp where ename like :P8_ENAME' and l_using got ':P8_ENAME' at "open ...." statement.
How can I get this cursor opened dynamically?
Thanks again!
DC

Similar Messages

  • FOR LOOP cursor that updates table A based on a value in table B

    Hi,
    I need a FOR LOOP cursor that scans and updates all pro-rata column in table EMPLOYEE(child) based on what pay classification all employees are on in the CLASSIFICATION(parent) table.
    DECLARE
    BEGIN
    IF employee.emp_type = 'FT' THEN
    UPDATE employee
    SET employee.pro_rata = ((classification.yearly_pay/52)*52)
    WHERE employee.empid = v_empid AND classification.class_id = employee.class_id;
    END IF;
    IF employee.emp_type = 'PT1' THEN
    UPDATE employee
    SET employee.pro_rata = ((classification.yearly_pay/39)*52)
    WHERE employee.empid = v_empid AND classification.class_id = employee.class_id;
    END IF;
    IF employee.emp_type = 'PT2' THEN
    UPDATE employee
    SET employee.pro_rata = ((classification.yearly_pay/21)*52)
    WHERE employee.empid = v_empid AND classification.class_id = employee.class_id;
    END IF;
    END;
    How do I create a cursor that cuts across these two table
    See tables and data
    CREATE TABLE CLASSIFICATION(
    CLASS_ID VARCHAR2(6) NOT NULL,
    CLASS_TYPE VARCHAR2(10),
    DESCRIPTION VARCHAR2(30) NOT NULL,
    YEARLY_PAY NUMBER(8),
    HOURLY_RATE NUMBER,
    WEEKDAY_OVER_TIME NUMBER,
    WEEKEND_OVER_TIME NUMBER,
    CONSTRAINT PK_CLASS_ID PRIMARY KEY (CLASS_ID));
    INSERT INTO CLASSIFICATION VALUES('PR1','PERMANENT','MANAGER',45000,'','',NULL);
    INSERT INTO CLASSIFICATION VALUES('PR2','PERMANENT','ADMIN ASSISTANT',22000,'',1.5,NULL);
    INSERT INTO CLASSIFICATION VALUES('PR3','PERMANENT','CONTROLLER',32000,'',1.5,NULL);
    INSERT INTO CLASSIFICATION VALUES('PR4','PERMANENT','CASH OFFICER',22000,'',1.5,NULL);
    INSERT INTO CLASSIFICATION VALUES('PR5','PERMANENT','CLEANERS',16000,'',1.5,NULL);
    INSERT INTO CLASSIFICATION VALUES('PR6','PERMANENT','ADMIN OFFICER',22000,'',1.5,NULL);
    INSERT INTO CLASSIFICATION VALUES('PR7','PERMANENT','WAREHOUSE ATTENDANT',20000,'',1.5,NULL);
    INSERT INTO CLASSIFICATION VALUES('PR8','PERMANENT','WINDOWS DRESSER',22000,'',1.5,NULL);
    INSERT INTO CLASSIFICATION VALUES('PR9','PERMANENT','DIRECTOR',60000,'','',NULL);
    INSERT INTO CLASSIFICATION VALUES('PR10','PERMANENT','DEPUTY DIRECTOR',52000,'','',NULL);
    INSERT INTO CLASSIFICATION VALUES('PR11','PERMANENT','SALES ASSISTANT',21000,'',1.5,NULL);
    INSERT INTO CLASSIFICATION VALUES('TEMP2','TEMP STAFF','ADMIN ASSISTANT','',16.50,'',NULL);
    INSERT INTO CLASSIFICATION VALUES('TEMP3','TEMP STAFF','CONTROLLER','',29.00,'',NULL);
    INSERT INTO CLASSIFICATION VALUES('TEMP4','TEMP STAFF','CASH OFFICER','',19.00,'',NULL);
    INSERT INTO CLASSIFICATION VALUES('TEMP5','TEMP STAFF','CLEANERS','',10.00,'',NULL);
    INSERT INTO CLASSIFICATION VALUES('TEMP6','TEMP STAFF','ADMIN OFFICER','',20.00,'',NULL);
    INSERT INTO CLASSIFICATION VALUES('TEMP7','TEMP STAFF','WAREHOUSE ATTENDANT','',18.00,'',NULL);
    INSERT INTO CLASSIFICATION VALUES('TEMP8','TEMP STAFF','WINDOWS DRESSER','',18.50,'',NULL);
    INSERT INTO CLASSIFICATION VALUES('TEMP11','TEMP STAFF','SALES ASSISTANT','',16.00,'',NULL);
    CREATE TABLE EMPLOYEE(
    EMPID NUMBER(5) NOT NULL,
    SURNAME VARCHAR2(30) NOT NULL,
    FNAME VARCHAR2(30) NOT NULL,
    GENDER CHAR(1) NOT NULL,
    DOB DATE NOT NULL,
    EMP_TYPE VARCHAR2(20) NOT NULL,
    ANNUAL_WEEKS_REQD NUMBER(2),
    PRO_RATA_WAGES NUMBER(7,2),
    HOLIDAY_ENTLMENT NUMBER(2),
    SICK_LEAVE_ENTLMENT NUMBER(2),
    HIRE_DATE DATE NOT NULL,
    END_DATE DATE,
    ACCNO NUMBER(8) NOT NULL,
    BANKNAME VARCHAR2(20) NOT NULL,
    BRANCH VARCHAR2(20) NOT NULL,
    ACCOUNTNAME VARCHAR2(20),
    CLASS_ID VARCHAR2(6),
    CONSTRAINT CK_HIRE_END CHECK (HIRE_DATE < END_DATE),
    CONSTRAINT CK_HIRE_DOB CHECK (HIRE_DATE >= ADD_MONTHS(DOB, 12 * 18)),
    CONSTRAINT CK_EMP_TYPE CHECK (EMP_TYPE IN ('FT','PT1','PT2','PT3','HOURLY')),
    CONSTRAINT CK_EMP_GENDER CHECK (GENDER IN ('M','F')),
    CONSTRAINT FK_EMP_CLASS FOREIGN KEY (CLASS_ID) REFERENCES CLASSIFICATION(CLASS_ID),
    CONSTRAINT PK_EMP PRIMARY KEY (EMPID));
    CREATE SEQUENCE SEQ_EMPID START WITH 1;
    INSERT INTO EMPLOYEE VALUES(
    SEQ_EMPID.NEXTVAL,'RICHARD','BRANDON','M','25-DEC-1966','FT',52,22000.00,28,14,'10-JAN-2005',NULL,90823227,'NATWEST','BROMLEY','DEPOSIT','PR2');
    INSERT INTO EMPLOYEE VALUES(
    SEQ_EMPID.NEXTVAL,'BOYCE','CODD','M','15-JAN-1972','PT1','','','','','12-JAN-2005',NULL,72444091,'LLOYDS','KENT','CURRENT','PR8');
    INSERT INTO EMPLOYEE VALUES(
    SEQ_EMPID.NEXTVAL,'ALHAJA','BROWN','F','20-MAY-1970','HOURLY','','','','','21-JUN-2000',NULL,09081900,'ABBEY','ESSEX','CURRENT','TEMP2');
    INSERT INTO EMPLOYEE VALUES(
    SEQ_EMPID.NEXTVAL,'RON','ATKINSON','M','10-AUG-1955','PT3','','','','','12-JAN-2005','26-MAR-2006',01009921,'HALIFAX','KENT','SAVINGS','PR6');
    INSERT INTO EMPLOYEE VALUES(
    SEQ_EMPID.NEXTVAL,'CHAMPI','KANE','F','01-JAN-1965','PT2','','','','','12-JAN-2004',NULL,98120989,'HSBC','ILFORD','CURRENT','PR4');
    INSERT INTO EMPLOYEE VALUES(
    SEQ_EMPID.NEXTVAL,'NED','VED','M','15-JAN-1980','HOURLY','','','','','29-DEC-2005',NULL,90812300,'WOOLWICH','LEWISHAM','CURRENT','TEMP6');
    INSERT INTO EMPLOYEE VALUES(
    SEQ_EMPID.NEXTVAL,'JILL','SANDER','F','22-MAR-1971','FT','','','','','30-NOV-2003',NULL,23230099,'BARCLAYS','PENGE','DEPOSIT','PR1');
    Any contribution would be appreciated
    many thanks
    Cube60

    Hi,
    I have triede this cursor procedure but I get an compilation error.
    See first post for tables and data..
    Can someone help me out please.
    SQL> CREATE OR REPLACE PROCEDURE update_employee(
    2 p_empid employee.empid%type,
    3 p_emp_type employee.emp_type%type)
    4 IS
    5 CURSOR c1 is
    6 select e.empid, e.emp_type, c.yearly_pay from employee e, classification c where
    7 c.class_id = e.class_id;
    8 BEGIN
    9 OPEN c1
    10 LOOP
    11 FETCH c1 INTO p_empid, p_emp_type;
    12 exit when c1%notfound;
    13
    14 IF v_emp_type ='PT1' THEN
    15 UPDATE employee SET annual_weeks_reqd = 39, pro_rata_wages = ((v_yearly_pay/52)*39), holiday_en
    tlment=21, sick_leave_entlment = 10.5 WHERE c.class_id = e.class_id;
    16 END IF;
    17 END;
    18 /
    Warning: Procedure created with compilation errors.
    SQL> SHOW ERR;
    Errors for PROCEDURE UPDATE_EMPLOYEE:
    LINE/COL ERROR
    10/1 PLS-00103: Encountered the symbol "LOOP" when expecting one of
    the following:
    . ( % ; for
    The symbol "; was inserted before "LOOP" to continue.
    Many thanks

  • How to get last Record ior Total rows in For Loop Cursor ?

    Hi Friends
    I would like to know , the last record in for loop cursor, i have the code in following format
    cursor c1 is
    select * from emp;
    begin
    for r1 in c1 loop
    v_total_rec := ? ( i would like to know total rows in the cursor , say for example if cursor has 10 rows, i want10 into this variable )
    v_count := v_count +1;
    dbms_output.put_line(r1.emp_name);
    end loop;
    end;
    Hope i am clear
    Any suggestions?
    Thanks
    Ravi

    Even though cursor loops are generally a Bad Idea ^tm^ as Dan says, here's an example of how you can get the information you wanted within the query itself...
    SQL> ed
    Wrote file afiedt.buf
      1  declare
      2    cursor c1 is
      3      select emp.*
      4            ,count(*) over (order by empno) as cnt
      5            ,count(*) over () as total_cnt
      6      from emp
      7      order by empno;
      8  begin
      9    for r1 in c1 loop
    10      dbms_output.put_line(r1.ename||' - row: '||r1.cnt||' of '||r1.total_cnt);
    11    end loop;
    12* end;
    SQL> /
    SMITH - row: 1 of 14
    ALLEN - row: 2 of 14
    WARD - row: 3 of 14
    JONES - row: 4 of 14
    MARTIN - row: 5 of 14
    BLAKE - row: 6 of 14
    CLARK - row: 7 of 14
    SCOTT - row: 8 of 14
    KING - row: 9 of 14
    TURNER - row: 10 of 14
    ADAMS - row: 11 of 14
    JAMES - row: 12 of 14
    FORD - row: 13 of 14
    MILLER - row: 14 of 14
    PL/SQL procedure successfully completed.
    SQL>

  • Using Dynamic Query in For Loop

    I have a doubt whether i can use the result from dynamic query in the for loop.
    for example,
    declare
    v_sql varchar2(1000);
    v_Id INTEGER;
    begin
    v_sql := 'select id from table1 where id in ('||v_Id||')';
    FOR i in vsql LOOP
    dbms_output.put_line(i.id);
    end loop;
    end;
    The above query is possible ?

    And here's a basic example of opening up a cursor for your dynamic query...
    SQL> ed
    Wrote file afiedt.buf
      1  declare
      2    v_sql varchar2(2000);
      3    v_cur sys_refcursor;
      4    i     emp.sal%type;
      5  begin
      6    v_sql := 'select sal from emp';
      7    open v_cur for v_sql;
      8    loop
      9      fetch v_cur into i;
    10      exit when v_cur%NOTFOUND;
    11      dbms_output.put_line('Salary: '||i);
    12    end loop;
    13* end;
    SQL> /
    Salary: 800
    Salary: 1600
    Salary: 1250
    Salary: 2975
    Salary: 1250
    Salary: 2850
    Salary: 2450
    Salary: 3000
    Salary: 5000
    Salary: 1500
    Salary: 1100
    Salary: 950
    Salary: 3000
    Salary: 1300
    PL/SQL procedure successfully completed.
    SQL>

  • Geting ORA 936 -while building dynamic query in for loop.

    HI,
    I hav written a SP and its compiled and giving me the results for the data I am quering but giving ORA936 - missing expressin and giving ORA 6512 at 2 lines. Please help me me out where I am going wrong.
    CREATE OR REPLACE TYPE LIST as VARRAY(5000) of NUMBER;
    CREATE OR REPLACE PROCEDURE test( V_id IN LIST,
    v-fdate IN DATE,
    v-tdate IN DATE,
    v_flg IN CHAR)
    AS
    TYPE opfld IS RECORD (
    FID TAB.ID%TYPE,
    FCURR TAB.CURR %TYPE,
    FCNT TAB.CNT%TYPE,
    FTOT TAB.TOT%TYPE );
    TYPE OPLIST IS REF CURSOR;
    Rc oplist;
    Edtab opfld;
    Selstr VACHAR2(200);
    Whstr1 VACHAR2(200);
    Whstr2 VACHAR2(200);
    Whstr3 VACHAR2(200);
    Whstr VACHAR2(200);
    Grpstr VACHAR2(200);
    Andstr VACHAR2(200);
    Fullstr VACHAR2(200);
    BEGIN
    Selstr := ‘SELECT col1,col2,sum(col3),sum(col4) from tab1 ’;
    Whstr1 := ‘ WHERE tdate BETWEEN TO_DATE(‘||’’’’||vfdate||’’’’||’)’;
    Whstr2: = ‘ AND TO_DATE(‘||’’’’||vtdate||’’’’||’)’;
    Whstr := whstr1||whstr2;
    Grpstr := ‘GROUP BY col1,col2’;
    IF v_flg IS NOT NULL THEN
    Whstr3 := whstr||’AND FLAG = ‘||v_flg;
    else
    Whstr3 := whstr ;
    END IF;
    FOR I IN 1..id.COUNT LOOP
    BEGIN
    Andstr := ‘ AND id =’|| v_id(i);
    Whstr := whstr3 || andstr ;
    Fullstr := selstr||whstr||grpstr;
    OPEN rc for fullstr;
    LOOP
    FETCH rc into edtab
    EXIT when rc%NOTFOUND;
    END LOOP;
    Andstr := ‘’;
    Whstr :=’’;
    END; ---BEGIN of FOR loop
    END LOOP; -- for end
    CLOSE rc;
    END; -- proc end
    Created above SP and its compiled. When I try to execute the SP with below code I am getting--
    DECLARE
    V_t LIST;
    BEGIN
    V_t:= LIST();
    V_t.EXTEND(10);
    V_t(1) := 10;
    V_t(2) := 20;
    Test(v_t,’25-APR-2012’,’30-APR-2012’,’Y’);
    END;
    The SP is building correct dynamic querry and its getting executed for id = 10 and 20, giving the correct results but though I defined only 2 ids while executing and written FOR lOOP upto ID.COUNT its building query for third time and that time its not getting id, so for the third time the last part of where clause is built like
    SELECT.....
    WHERE....
    AND id = (its taking blank here)
    GROUP BY ...;
    and thus its giving me ORA 936 missing expression and ORA 06152 at line of RECORD TYPE declaration and line of OPEN rc for fullstr;
    ERROR at line 1
    ORA 00936 misssing expresiion
    ORA 006152 at line 9
    ORA 006512 at line 87
    I hav put DBMS_OUTPUT statements @ every build of dynamic wuery and its correct. here I have not copid the code I hav typed hereso not wriiten DBMS_OUTPUT.
    I tried lot of ways redefining Andstr := ‘’;
    Whstr :=’’; after for endloop but its giving the same error. is this because I am using varray? If am providing 2 ids in anonymous block then how its building query for third blank ID value.
    Please help me out here..
    Thanks a lot..

    >
    I hav written a SP and its compiled and giving me the results for the data I am quering
    >
    Then you should have posted the one that compiles and gives you results.
    The code you posted will not compile without errors. Edit your original post and provide the corrected code.
    When you do please add \ tags on the line before and after the code to preserve formatting. See the FAQ for details.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

  • Having trouble with inner for loop values in my procedure

    Hi ...
    I am using oracle 10g and here is my procedure ...
    create or replace procedure sales_information is
    v_qty number(10);
    rem_qty number(10):=0;
    cursor pck_quantity is
    select * from sales_info;
    cursor no_of_labels is
    select ceil(sum(nvl(total_quantity,actual_quantity))/400) from sales_info;
    begin
    for j in no_of_labels
    loop
    for i in pck_quantity
    loop
    select nvl(i.total_quantity,i.actual_quantity) into v_qty from sales_info;
    if v_qty>=i.packed_quantity and rem_qty=0 then
    insert into sales_order values------------
    rem-qty:=v_qty-i.packed_quantity;
    v_qty:=rem_qty;
    exit;
    else if v_qty>=i.packed_quantity and rem_qty>=400 then
    insert into sales_order values-----------
    rem_qty:=v_qty-rem_qty;
    v_qty:=rem_qty;
    exit;
    else if v_qty>=i.packed_quantity and rem_qty>0 then
    rem_qty:=v_qty+rem_qty-i.packed_quantity;
    v_qty:=rem_qty;
    insert into sales_order values-----------
    else if v_qty is null and rem_qty>0 and then
    insert into sales_order values-----------
    else if v_qty<i.packed_quantity and rem_qty:=0 then
    rem_qty:=v_qty;
    else if v_qty<i.packed_quantity and rem_qty>0 then
    if (v_qty+rem_qty)>400 then
    insert into sales_order values-----------
    rem_qty:=v_qty+rem_qty-i.packed_quantity;
    v_qty:=rem_qty;
    end if;
    end if;
    end loop;
    end loop;
    The inner for loop will retrieve the same values of v_qty for every iteration of outer for loop when it runs the following select statement:
    select nvl(i.total_quantity,i.actual_quantity) into v_qty from sales_info;
    and thus loses the previously computed values of v_qty and rem_qty
    in the previous iteration of outer for loop whereas i want the inner for loop to iterate over it's previously computed values of v_qty and rem_qty but cant think of a workaround.

    h4. Thanks Dave for explanation. Hope I understood your requirement and below code resolves that
    -- Creating table SALES_INFO
    CREATE TABLE SALES_INFO
    (    S_NO             NUMBER(1),
         ACTUAL_QUANTITY  NUMBER(10),
         TOTAL_QUANTITY   NUMBER(10),
          PACKED_QUANTITY  NUMBER(10)
    -- Creating table sales_order
    CREATE TABLE SALES_ORDER
    (    S_NO             NUMBER(1),
         LABEL            VARCHAR2(30),
         ORDER_QUANTITY   NUMBER(10)
    -- Push SALES_INFO data
    INSERT INTO SALES_INFO VALUES(1,1000,800,400);
    INSERT INTO SALES_INFO VALUES(2,800,600,400);
    INSERT INTO SALES_INFO VALUES(3,800,NULL,400);
    INSERT INTO SALES_INFO VALUES(4,NULL,600,400);
    CREATE OR REPLACE PROCEDURE populate_sales_order AS
    CURSOR get_sales_info IS
    SELECT s_no,
               NVL(total_quantity,actual_quantity) total_quantity,
            packed_quantity
    FROM   sales_info;
    v_s_no          PLS_INTEGER := 0;
    v_rem_qty     PLS_INTEGER := 0;
    v_label_num   PLS_INTEGER := 1;
    BEGIN
    FOR rec IN get_sales_info LOOP
        v_rem_qty := rec.total_quantity + v_rem_qty;
        v_s_no    := rec.s_no;
         WHILE v_rem_qty >= rec.packed_quantity LOOP
           INSERT INTO sales_order( s_no, label, order_quantity)
           VALUES ( v_s_no, 'LABEL' || v_label_num, rec.packed_quantity );
           -- Reduce the packed qty from total qty and increment label counter
           v_rem_qty   := v_rem_qty - rec.packed_quantity ;
           v_label_num := v_label_num + 1;
         END LOOP;
    END LOOP;
    -- Put the last lot remaining qty into last carton
    IF v_rem_qty > 0 THEN
    INSERT INTO sales_order( s_no, label, order_quantity)
    VALUES (v_s_no, 'LABEL' || v_label_num, v_rem_qty );
    END IF;
    COMMIT;
    END;
    S_NO    LABEL                                ORDER_QUANTITY
      1          LABEL1                                    400
      1          LABEL2                                    400
      2          LABEL3                                    400
      3          LABEL4                                    400
      3          LABEL5                                    400
      4          LABEL6                                    400
      4          LABEL7                                    400
    {code}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • Having errors in basic for loop

    Folks
    I am tring to write SQL script that implements a block that contains a for-loop which increments a counter from 1 to 10 and inserts the counter value into the results field of the LOOPING table that i have created. i want to insert a null val in place of the counter if the counter value is equal to either 6 or 8.
    Below are my work
    Table creation
    CREATE TABLE LOOPING (Result VARCHAR2(60));
    I am expecting a output like this
    Result
    1
    2
    3
    4
    5
    NULL
    7
    Null
    9
    10
    My SCRIPT
    BEGIN
    FOR COUNTER IN 1..10
    IF ((COUNTER = 6 ) AND (COUNTER = 8 ))
    THEN
    INSERT INTO MESSAGES
    VALUES(NULL);
    ELSE
    INSERT INTO MESSAGES
    VALUES(COUNTER);
    END LOOP;
    END;
    I am getting errors. I am a beginner . Please help me out .
    can you point out my errors and explain
    And finaly please tell me how to correct it .
    Thanks
    Guna

    1) When you get an error, it's always helpful to post the details of that error (the error number and the line number). That makes it far easier for us to help you.
    2) Thank you for posting your code and table definition. That definitely helps! In the future, you'll want to use the \ tag (6 characters, all lower case) before and after any code fragments to preserve the white space & indentation.  That makes your code far easier to read.
    3) Your code fails to compile because
    - you are missing the LOOP keyword between lines 2 and 3
    - you are missing the END IF at the end of your IF statement
    - you are referring to a table named MESSAGES while your CREATE TABLE statement refers to a table named LOOPING
    If you correct those three errors, your code will compile
    [code]
    SQL> ed
    Wrote file afiedt.buf
      1  BEGIN
      2    FOR COUNTER IN 1..10
      3    LOOP -- Added
      4      IF ((COUNTER = 6 ) AND (COUNTER = 8 ))
      5      THEN
      6        INSERT INTO looping -- Changed table name
      7          VALUES(NULL);
      8      ELSE
      9        INSERT INTO looping -- Changed table name
    10          VALUES(COUNTER);
    11      END IF; -- Added
    12    END LOOP;
    13* END;
    SQL> /
    PL/SQL procedure successfully completed.
    [/code]
    4) However, now that the code compiles, you'll have a problem that it does not meet the requirements.  It will never insert a NULL value because your IF condition is incorrect.  Since this looks like a homework problem, however, I don't want to completely give it away-- I've probably done more than I should have already.
    Justin                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

  • Dynamic For loop in Oracle 10g

    Hi ,
    my requirement is to write dynamic for loop , Some thing similar to below plsql block, But I am getting error , please suggest
    declare
    lv_text varchar2(200);
    begin
    lv_text:='select * from some_table ';
    for i in (lv_text)
    loop
    null;
    end loop;
    end;
    **** Here my purpose of lv_text is to use a dynamic query in for loop.

    You are getting error because lv_Text is not a cursor variable.... So you can try this way..if your statement is known...
    begin
    For rec in (select * from emp)
    loop
    dbms_output.put_line(rec.ename);
    end loop;
    end;
    Or try this if your statements can be controlled based on your addition input(cnt)
    create or replace procedure p_ref_Cursor
    +(p_Empno in number,p_ename out varchar2,p_sal out number,cnt number)+
    is
    Type ref_cursor is ref cursor;
    e_ref_Cursor ref_Cursor;
    begin
    if cnt =1 then
    open e_Ref_Cursor for select ename from emp where empno=p_Empno;
    fetch e_ref_cursor into p_ename;
    else
    open e_Ref_Cursor for select sal from emp where empno=p_Empno;
    fetch e_ref_cursor into p_sal;
    end if;
    close e_ref_cursor;
    end;
    or Use dbms_sql package for creating dynamic SQL as suggested by others too if your statement is completely dynamic ..:)

  • Cursor for loop in PlSql

    while i was studying about cursor for loop i found this statement in the web
    "A cursor FOR loop implicitly declares its loop index as a %ROWTYPE record"
    for example an emp table contain following columns empno,ename,sal,hiredate,deptno
    and let us consider an cursor for loop as
    for rec in select empno,sal from emp loop
    if cursor for loop declare loop index as a %rowtype our cursor statement should include all the columns and follow the data type compatabulity.
    But here our cursor statement includes only few columns,if we use %rowtype we have to select all columns but here we are not doing this.
    Can anyone please explain what is happening in cursor for loop?

    for loop cursor is also like the simple explicite cursor..
    the cursor variable will hold only the columns that are given in select statement of the cursor..
    if u declare a cursor as %rowtype, then it should include all the columns of that particular table..
    otherwise u should use only %type for each and every column seperately only...

  • For loop prob - PLEASE HELP!

    I am having problems with a for loop. This for loop is nested within some other for loop. the problem I'm having is that the for loop executes once and then exits to execute the outer for loop. my initial reaction was that my condition (in the for loop ) was false the second time round thus resulting in the exit. I'm usually told to paste some code so i'll do that:
    for (int i=0; i<row.size(); ++i){
      for (int all = 1; all < row.size();all++){
       try{          
         for (int k=0; k< column.size();  k++){
         System.out.println(" column size " + column.size());
         Long longObject1 = (Long)((Vector)row.get(i)).get(k);
         System.out.println(" getting" + longObject1);
    }                              �
         for (int k=0; k< column.size(); k++){ is the loop causing me problems.  column.size() evaluates to 2 so what is the problem?

    No I don't think there is another thread effecting column -I have even placed a Println to show what the value of column is. At present the value of column is 2 so the for loop should execute twice.
    I have a catch block which catches ClassCastException. The second element in row is not null. Furthermore, the size of count is 2 so the for loop should execute twice.
    yes the first element in row is another vector. (Row is a vector of vectors). I've looked at the other suggestions too but even after considering these i am left with the same problem. Any other suggestions? I could do with all the help I can get. Thanks

  • How to pass parameter to cursor for loop having table type?

    Hi Friends,
    I am wondering how to pass a parameter into second for loop in the example code below.Please see the bold statements and answer my queries.
    Thanks a lot .Here is the code .
    declare
    l_bom_header_tbl BOM_BO_PUB.BOM_HEADER_TBL_TYPE ; ---TABLE TYPE
    V_bom_header_tbl Bom_Bo_Pub.Bom_Head_Rec_Type := Bom_Bo_Pub.G_MISS_BOM_HEADER_REC; ---Record type
    v_bom_components_tbl Bom_Bo_Pub.Bom_Comps_Tbl_Type := Bom_Bo_Pub.G_MISS_BOM_COMPONENT_TBL;---nested table type
    c:=0 number ;
    k:=1 number ;
    begin
    BOMPXINQ.Export_BOM(
    P_org_hierarchy_name => l_org_hierarchy_name,
    P_assembly_item_name => l_assembly_item_name,
    P_organization_code => l_organization_code,
    P_alternate_bm_designator => '1Test',
    P_Costs => l_costs,
    P_Cost_type_id => l_cost_type_id,
    X_bom_header_tbl => l_bom_header_tbl,
    X_bom_revisions_tbl => l_bom_revisions_tbl,
    X_bom_components_tbl => l_bom_components_tbl,
    X_bom_ref_designators_tbl => l_bom_ref_designators_tbl,
    X_bom_sub_components_tbl => l_bom_sub_components_tbl,
    X_bom_comp_ops_tbl => l_bom_comp_ops_tbl,
    X_Err_Msg => l_Err_Msg,
    X_Error_Code => l_Error_Code);
    if l_Error_Code = 0 then
    for i in 1 .. l_bom_header_tbl.COUNT LOOP
    V_bom_header_tbl.organization_code :='DSC';
    Can we assign a table type to record type like below statement?
    V_bom_header_tbl.assembly_item_name:= l_bom_header_tbl(i).assembly_item_name ;
    k:=1;
    I want to pass parameter  l_bom_header_tbl(i).assembly_item_name  into the for statement below: How to achieve this?
    for j in 1 .. l_bom_components_tbl.COUNT LOOP
    Can we assign a table type to table  type like below statement?
    v_bom_components_tbl(k).Assembly_Item_name := l_bom_header_tbl(i).assembly_item_name ;
    k := k + 1;
    end LOOP;
    end loop;
    end;
    Edited by: ILovePlSql on Mar 22, 2010 7:51 AM
    Edited by: ILovePlSql on Mar 22, 2010 8:16 AM

    ILovePlSql wrote:
    V_bom_header_tbl.assembly_item_name:= l_bom_header_tbl(i).assembly_item_name ;
    v_bom_header_tabl is a record type and l_bom_header_tbl is a table type .So is the above statement ok?I asked you for type definition. Please provide definition of BOM_BO_PUB.BOM_HEADER_TBL_TYPE and Bom_Bo_Pub.Bom_Head_Rec_Type. If BOM_BO_PUB.BOM_HEADER_TBL_TYPE is table of Bom_Bo_Pub.Bom_Head_Rec_Type then your statment is OK. For example:
    SQL> declare
      2      type BOM_HEADER_TBL_TYPE is table of emp%rowtype index by binary_integer;
      3      l_bom_header_tbl BOM_HEADER_TBL_TYPE;
      4      V_bom_header_tbl emp%rowtype;
      5  begin
      6      select * bulk collect into l_bom_header_tbl from emp;
      7      for i in 1 .. l_bom_header_tbl.count loop
      8        V_bom_header_tbl.ename := l_bom_header_tbl(i).ename;
      9      end loop;
    10  end;
    11  /
    PL/SQL procedure successfully completed.
    SQL> SY.

  • Why use cursor and for loop?

    Hi All
    So in general why would we use a cursor and a for loop to do update in a stored procedure?
    Why wouldnt we just use a single update statement ?
    is there compelling reason for using a cursor and a for loop: I am reading some code from a co-worker that the business logic for the select (set need to be updated) is complex but the update logic is simple (just set a flag to (0 or 1 or 2 or 3 or 4).
    But eventually the select come down to a key (row_id) so I re-write it using just a single sql statement.
    The size of the main table is about 2.6 to 3million rows
    Any thoughts on that??
    The code below I just do a google for cursor for update example in case for something to play with
    -Thanks for all your input
    create table f (a number, b varchar2(10));
    insert into f values (5,'five');
    insert into f values (6,'six');
    insert into f values (7,'seven');
    insert into f values (8,'eight');
    insert into f values (9,'nine');
    commit;
    create or replace procedure wco as
      cursor c_f is
        select a,b from f where length(b) = 5 for update;
        v_a f.a%type;
        v_b f.b%type;
    begin
      open c_f;
      loop
        fetch c_f into v_a, v_b;
        exit when c_f%notfound;
        update f set a=v_a*v_a where current of c_f;
      end loop;
      close c_f;
    end;
    exec wco;
    select * from f;
    drop table f;
    drop procedure wco;
    Joining multiple tables
    create table numbers_en (
      id_num  number        primary key,
      txt_num varchar2(10)
    insert into numbers_en values (1, 'one'  );
    insert into numbers_en values (2, 'two'  );
    insert into numbers_en values (3, 'three');
    insert into numbers_en values (4, 'four' );
    insert into numbers_en values (5, 'five' );
    insert into numbers_en values (6, 'six'  );
    create table lang (
       id_lang   char(2) primary key,
       txt_lang  varchar2(10)
    insert into lang values ('de', 'german');
    insert into lang values ('fr', 'french');
    insert into lang values ('it', 'italian');
    create table translations (
      id_num    references numbers_en,
      id_lang   references lang,
      txt_trans varchar2(10) not null
    insert into translations values (1, 'de', 'eins'   );
    insert into translations values (1, 'fr', 'un'     );
    insert into translations values (2, 'it', 'duo'    );
    insert into translations values (3, 'de', 'drei'   );
    insert into translations values (3, 'it', 'tre'    );
    insert into translations values (4, 'it', 'quattro');
    insert into translations values (6, 'de', 'sechs'  );
    insert into translations values (6, 'fr', 'six'    );
    declare
      cursor cur is
          select id_num,
                 txt_num,
                 id_lang,
                 txt_lang,
                 txt_trans
            from numbers_en join translations using(id_num)
                       left join lang         using(id_lang)
        for update of translations.txt_trans;
      rec cur%rowtype;
    begin
      for rec in cur loop
        dbms_output.put (
          to_char (rec.id_num         , '999') || ' - ' ||
          rpad    (rec.txt_num        ,   10 ) || ' - ' ||
          rpad(nvl(rec.txt_trans, ' '),   10 ) || ' - ' ||
                   rec.id_lang                 || ' - ' ||
          rpad    (rec.txt_lang       ,   10 )
        if mod(rec.id_num,2) = 0 then
          update translations set txt_trans = upper(txt_trans)
           where current of cur;
           dbms_output.put_line(' updated');
        else
          dbms_output.new_line;
        end if;
      end loop;
    end;
    /Edited by: xwo0owx on Apr 25, 2011 11:23 AM

    Adding my sixpence...
    PL/SQL is not that different from a SQL perspective than any other SQL client language like Java or C# or C/C++. PL/SQL simply integrates the 2 languages a heck of a lot better and far more transparent than the others. But make no mistake in that PL/SQL is also a "client" language from a SQL perspective. The (internal) calls PL/SQL make to the SQL engine, are the same (driver) calls made to the SQL engine when using Java and C and the others.
    So why a cursor and loops in PL/SQL? For the same reason you have cursors and loops in all these other SQL client languages. There are the occasion that you need to pull data from the SQL engine into the local language to perform some very funky and complex processing that is not possible using the SQL language.
    The danger is using client cursor loop processing as the norm - always pulling rows into the client language and crunching it there. This is not very performant. And pretty much impossible to scale. Developers in this case views the SQL language as a mere I/O interface for reading and writing rows. As they would use the standard file I/O read() and write() interface calls.
    Nothing could be further from the truth. SQL is a very advance and sophisticated data processing language. And it will always be faster than having to pull rows to a client language and process them there. However, SQL is not Turing complete. It is not the procedural type language that most other languages we use, are. For that reason there are things that we cannot do in SQL. And that should be the only reason for using the client language, like PL/SQL or the others, to perform row crunching using a client cursor loop.

  • Cursor For Loop SQL/PL right application? Need help with PL Performance

    I will preface this post by saying that I am a novice Oracle PL user, so an overexplanation would not be an issue here.
    Goal: Run a hierarchial query for over 120k rows and insert output into Table 1. Currently I am using a Cursor For Loop that takes the first record and puts 2 columns in "Start" section and "connect by" section. The hierarchial query runs and then it inserts the output into another table. I do this 120k times( I know it's not very efficient). Now the hierarchial query doesn't take too long ( run by itself for many parts) but this loop process is taking over 9 hrs to run all 120k records. I am looking for a way to make this run faster. I've read about "Bulk collect" and "forall", but I am not understanding how they function to help me in my specific case.
    Is there anyway I can rewrite the PL/SQL Statement below with the Cursor For loop or with another methodology to accomplish the goal significantly quicker?
    Below is the code ( I am leaving some parts out for space)
    CREATE OR REPLACE PROCEDURE INV_BOM is
    CURSOR DISPATCH_CSR IS
    select materialid,plantid
    from INV_SAP_BOM_MAKE_UNIQUE;
    Begin
    For Row_value in Dispatch_CSR Loop
    begin
    insert into Table 1
    select column1
    ,column2
    ,column3
    ,column4
    from( select ..
    from table 3
    start with materialid = row_value.materialid
    and plantid = row_value.plantid
    connect by prior plantid = row.value_plantid
    exception...
    end loop
    exception..
    commit

    BluShadow:
    The table that the cursor is pulling from ( INV_SAP_BOM_MAKE_UNIQUE) has only 2 columns
    Materialid and Plantid
    Example
    Materialid Plantid
    100-C 1000
    100-B 1010
    X-2 2004
    I use the cursor to go down the list 1 by 1 and run a hierarchical query for each row. The only reason I do this is because I have 120,000 materialid,plantid combinations that I need to run and SQL has a limit of 1000 items in the "start with" if I'm semi-correct on that.
    Structure of Table it would be inserted into ( Table 1) after Hierarchical SQL Statement runs:
    Materialid Plantid User Create Column1 Col2
    100-C 1000 25 EA
    The Hierarchical query ran gives the 2 columns at the end.
    I am looking for a way to either just run a quicker SQL or a more efficient way of running all 120,000 materialid, plantid rows through the Hierarchial Query.
    Any Advice? I really appreciate it. Thank You.

  • Problem in executing cursor for loop

    hi all,
    I am facing following problem.
    We are using cron utility on unix to run pl/sql stored procedure.
    This procedure in turn calls separate procedures. However any one of the procedure does not end in pl/sql even though it has completed its intended processing.
    We are using cursor for loop for data processing and also using database link to fetch data from other instance.
    Can anyone help me on possible reasons for this problem

    The proc only needs a single 'open s_cursor for ...' statement where the query is a join between all the tables involved. You have obfuscated your query so much in the post that I can't construct it for you (your second select doesn't even join to the 's' table), but the point is that you don't need a cursor loop, just a single query.

  • Bulk collect usage in cursor for loop

    Hi Team,
    I have one cursor like below assuming cursor is having 3000 records,
    CURSOR csr_del_frm_stg(c_source_name VARCHAR2 , c_file_type VARCHAR2)
    IS
    SELECT stg.last_name,stg.employee_number,stg.email
    FROM akam_int.xxak_eb_contact_stg stg
    MINUS
    SELECT ss.last_name,ss.employee_number,ss.email
    FROM akam_int.xxak_eb_contact_stg_ss ss;
    I declared one record type variable as,
    TYPE emp_rec IS RECORD (LAST_NAME             VARCHAR2(40)
    *,EMPLOYEE_NUMBER VARCHAR2(50)*
    *,EMAIL VARCHAR2(80)*
    TYPE emp_rec_ss IS VARRAY(3000) OF emp_rec;
    Im updating the status of those cursor records to 'C' in the below for loop,
    FOR l_csr_del_frm_stg IN csr_del_frm_stg(p_source_name , p_file_type)
    LOOP
    FETCH csr_del_frm_stg BULK COLLECT INTO emp_rec_ss LIMIT 500;
    FORALL i IN emp_rec_ss.FIRST..emp_rec_ss.LAST
    UPDATE akam_int.xxak_eb_contact_stg stg
    SET akam_status_flag    = 'C'
    WHERE stg.employee_number = emp_rec_ss(i).employee_number;
    EXIT WHEN csr_del_frm_stg%NOTFOUND;
    END LOOP;
    Getting following errors if i compile the code,
    PLS-00321: expression 'EMP_REC_SS' is inappropriate as the left hand side of an assignment statement
    PLS-00302: component 'FIRST' must be declared

    Use cursor variables:
    declare
        v_where varchar2(100) := '&where_clause';
        v_cur sys_refcursor;
        v_ename varchar2(30);
    begin
        open v_cur for 'select ename from emp where ' || v_where;
        loop
          fetch v_cur into v_ename;
          exit when v_cur%notfound;
          dbms_output.put_line(v_ename);
        end loop;
        close v_cur;
    end;
    Enter value for where_clause: deptno = 10
    CLARK
    KING
    MILLER
    PL/SQL procedure successfully completed.
    SQL> /
    Enter value for where_clause: sal = 5000
    KING
    PL/SQL procedure successfully completed.
    SQL> /
    Enter value for where_clause: job = ''CLERK''
    SMITH
    ADAMS
    JAMES
    MILLER
    PL/SQL procedure successfully completed.
    SQL>  SY.

Maybe you are looking for