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
Cube60Hi,
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
RaviEven 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
Guna1) 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 ..:) -
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 AMILovePlSql 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 AMAdding 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..
commitBluShadow:
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 problemThe 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 declaredUse 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
-
How to do Subsitution of Tables
I need to looking for every tables that have one column with the same name. (Select table_name from dba_tab_columns where column_name like 'ACCOUNTING') After, I need to looking for each one tables a value into that column. But my problem is how to d
-
Diagnosing issues (and a real issue)
I have a webapp that runs on JRockit with 8.1sp1. The webapp does a lot of network and file I/O. At some point the box CPU jumps to 100% and stays there. The only way to get the webapp to "come back" is to restart the JVM. This "some point" has been
-
Where can I find the third party app? I'm really in trouble that I can't record and check my blood glucose. Of cause I exported the data from app, but It's not readable for me. Please reply ASAP and give me other solution.
-
Fail to configure Apache web server 2.0.53 as plugin to weblogicserver 8.1
Hello, I have installed web logic server 8.1 with sp2 on windows XP system. I have configured a domain with configuration wizard with these settings - server name "myServer" port No - 7001 Domain - mydomain I have installed apache web server 2.0.53 o
-
Help with running sun jndi tutorial example LookUp.class
I am learning JNDI,and when I run LookUp.java available in JNDI TUTORIAL ,souce code here: * @(#)Lookup.java 1.3 99/08/12 * Copyright 1997, 1998, 1999 Sun Microsystems, Inc. All Rights * Reserved. * Sun grants you ("Licensee") a non-exclusive, ro