![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
DBMS_ERRLOG will not compile within a cursor loop. Depending upon where I put the semicolons, I get these types of error messages. PLS-00103: Encountered the symbol "ERRORS" when expecting one of the following: := . ( @ % ; or (S6019) Expecting: ; RETURN RETURNING Any ideas on how I re-write to code below to work? I can make it work with a regular non-looping insert statement from sqlPlus or PL/SQL Thanks! Alex Glaros FOR c1_rec IN c1_accu_actions LOOP INSERT INTO ACCUSATION_ACTIONS ( id, acn_id, case_type, ate_code, ate_pgm_code, action_date, description, css_copy_id_create, reference ) VALUES ( c1_rec.seq, c1_rec.id, c1_rec.case_type, c1_rec.action_code, c1_rec.agency, c1_rec.action_date, c1_rec.action_desc, c1_rec.p_copy_id, c1_rec.reference ) LOG ERRORS INTO ACCUS_ACTIONS_ERR_LOG REJECT LIMIT 100; v_recount := v_recount + 1; IF (v_recount > 100) THEN v_recount := 0; COMMIT; END IF; END LOOP; COMMIT; |
#3
| |||
| |||
|
|
alexglaros (AT) gmail (DOT) com wrote: DBMS_ERRLOG will not compile within a cursor loop. Depending upon where I put the semicolons, I get these types of error messages. PLS-00103: Encountered the symbol "ERRORS" when expecting one of the following: := . ( @ % ; or (S6019) Expecting: ; RETURN RETURNING Any ideas on how I re-write to code below to work? I can make it work with a regular non-looping insert statement from sqlPlus or PL/SQL Thanks! Alex Glaros FOR c1_rec IN c1_accu_actions LOOP INSERT INTO ACCUSATION_ACTIONS ( id, acn_id, case_type, ate_code, ate_pgm_code, action_date, description, css_copy_id_create, reference ) VALUES ( c1_rec.seq, c1_rec.id, c1_rec.case_type, c1_rec.action_code, c1_rec.agency, c1_rec.action_date, c1_rec.action_desc, c1_rec.p_copy_id, c1_rec.reference ) LOG ERRORS INTO ACCUS_ACTIONS_ERR_LOG REJECT LIMIT 100; v_recount := v_recount + 1; IF (v_recount > 100) THEN v_recount := 0; COMMIT; END IF; END LOOP; COMMIT; Sure it will: SQL> CREATE TABLE t AS 2 SELECT * 3 FROM all_tables 4 WHERE 1=2; Table created. SQL SQL> ALTER TABLE t 2 ADD CONSTRAINT pk_t 3 PRIMARY KEY (owner, table_name) 4 USING INDEX; Table altered. SQL SQL> ALTER TABLE t 2 ADD CONSTRAINT cc_t 3 CHECK (blocks < 11); Table altered. SQL> exec dbms_errlog.create_error_log('T'); PL/SQL procedure successfully completed. SQL> BEGIN 2 INSERT /*+ APPEND */ INTO t 3 SELECT * 4 FROM all_tables 5 LOG ERRORS 6 REJECT LIMIT UNLIMITED; 7 END; 8 / PL/SQL procedure successfully completed. SQL |
#4
| |||
| |||
|
|
Now my examples does not include a cursor loop. But if you have DMBS_ERRLOG then you are in a version of Oracle more recent than 8i. And that means you've no reason for ever writing a cursor loop: Ever! |
#5
| |||
| |||
|
|
It can save you a lot of typing. Is it worth an extra 1000 keystrokes in code to save one or two microseconds in execution time? Really? |
#6
| |||
| |||
|
|
On Nov 1, 11:26 am, DA Morgan <damor... (AT) psoug (DOT) org> wrote: Now my examples does not include a cursor loop. But if you have DMBS_ERRLOG then you are in a version of Oracle more recent than 8i. And that means you've no reason for ever writing a cursor loop: Ever! It can save you a lot of typing. Is it worth an extra 1000 keystrokes in code to save one or two microseconds in execution time? |
#7
| |||
| |||
|
|
Ken Denny wrote: On Nov 1, 11:26 am, DA Morgan <damor... (AT) psoug (DOT) org> wrote: Now my examples does not include a cursor loop. But if you have DMBS_ERRLOG then you are in a version of Oracle more recent than 8i. And that means you've no reason for ever writing a cursor loop: Ever! It can save you a lot of typing. Is it worth an extra 1000 keystrokes in code to save one or two microseconds in execution time? Lets see ... with cursor loop. CREATE OR REPLACE PROCEDURE slow_way IS BEGIN FOR r IN (SELECT * FROM parent) LOOP -- modify record values r.part_num := r.part_num * 10; -- store results INSERT INTO child VALUES (r.part_num, r.part_name); END LOOP; COMMIT; END slow_way; / -- 7.71 seconds without cursor loop. CREATE OR REPLACE PROCEDURE fast_way IS TYPE myarray IS TABLE OF parent%ROWTYPE; l_data myarray; CURSOR r IS SELECT part_num, part_name FROM parent; BEGIN OPEN r; LOOP FETCH r BULK COLLECT INTO l_data LIMIT 1000; FOR j IN 1 .. l_data.COUNT LOOP l_data(1).part_num := l_data(1).part_num * 10; END LOOP; FORALL i IN 1..l_data.COUNT INSERT INTO child VALUES l_data(i); EXIT WHEN r%NOTFOUND; END LOOP; COMMIT; CLOSE r; END fast_way; / -- 0.50 seconds SARCASM Oh my gawd my fingers are killing me. All the heavy lifting and hard work. Please excuse me for a minute. I need to sit down and catch my breath ... make an appointment to have my carpel tunnel syndrome treated ... make out my will. And all I did was speed the code up by a lousy 15.42 times. Hardly worth it eh. /SARCASM Good thing the web is near anonymous Ken. You might have just talked yourself out of quite a few job opportunities if recruiters look for you on the web. A few microseconds my .... -- Daniel A. Morgan University of Washington damorgan@x.washington.edu (replace x with u to respond) Puget Sound Oracle Users Group www.psoug.org |
#8
| |||
| |||
|
|
"DA Morgan" <damorgan (AT) psoug (DOT) org> schreef in bericht news:1193950181.169048 (AT) bubbleator (DOT) drizzle.com... Ken Denny wrote: On Nov 1, 11:26 am, DA Morgan <damor... (AT) psoug (DOT) org> wrote: Now my examples does not include a cursor loop. But if you have DMBS_ERRLOG then you are in a version of Oracle more recent than 8i. And that means you've no reason for ever writing a cursor loop: Ever! It can save you a lot of typing. Is it worth an extra 1000 keystrokes in code to save one or two microseconds in execution time? Lets see ... with cursor loop. CREATE OR REPLACE PROCEDURE slow_way IS BEGIN FOR r IN (SELECT * FROM parent) LOOP -- modify record values r.part_num := r.part_num * 10; -- store results INSERT INTO child VALUES (r.part_num, r.part_name); END LOOP; COMMIT; END slow_way; / -- 7.71 seconds without cursor loop. CREATE OR REPLACE PROCEDURE fast_way IS TYPE myarray IS TABLE OF parent%ROWTYPE; l_data myarray; CURSOR r IS SELECT part_num, part_name FROM parent; BEGIN OPEN r; LOOP FETCH r BULK COLLECT INTO l_data LIMIT 1000; FOR j IN 1 .. l_data.COUNT LOOP l_data(1).part_num := l_data(1).part_num * 10; END LOOP; FORALL i IN 1..l_data.COUNT INSERT INTO child VALUES l_data(i); EXIT WHEN r%NOTFOUND; END LOOP; COMMIT; CLOSE r; END fast_way; / -- 0.50 seconds SARCASM Oh my gawd my fingers are killing me. All the heavy lifting and hard work. Please excuse me for a minute. I need to sit down and catch my breath ... make an appointment to have my carpel tunnel syndrome treated ... make out my will. And all I did was speed the code up by a lousy 15.42 times. Hardly worth it eh. /SARCASM Good thing the web is near anonymous Ken. You might have just talked yourself out of quite a few job opportunities if recruiters look for you on the web. A few microseconds my .... -- Daniel A. Morgan University of Washington damorgan@x.washington.edu (replace x with u to respond) Puget Sound Oracle Users Group www.psoug.org Daniel, I think error handling should be at the start of the loop and could be EXIT WHEN l_data.COUNT = 0; which might save another millisecond... <g Picked this from the net: "Also, within the loop (using LIMIT), you cannot rely on cursor%FOUND to determine if the last fetch returned any rows." But maybe this has changed over the years? Shakepeare |
#9
| |||
| |||
|
|
Ken Denny wrote: On Nov 1, 11:26 am, DA Morgan <damor... (AT) psoug (DOT) org> wrote: Now my examples does not include a cursor loop. But if you have DMBS_ERRLOG then you are in a version of Oracle more recent than 8i. And that means you've no reason for ever writing a cursor loop: Ever! It can save you a lot of typing. Is it worth an extra 1000 keystrokes in code to save one or two microseconds in execution time? Lets see ... with cursor loop. CREATE OR REPLACE PROCEDURE slow_way IS BEGIN FOR r IN (SELECT * FROM parent) LOOP -- modify record values r.part_num := r.part_num * 10; -- store results INSERT INTO child VALUES (r.part_num, r.part_name); END LOOP; COMMIT; END slow_way; / -- 7.71 seconds without cursor loop. CREATE OR REPLACE PROCEDURE fast_way IS TYPE myarray IS TABLE OF parent%ROWTYPE; l_data myarray; CURSOR r IS SELECT part_num, part_name FROM parent; BEGIN OPEN r; LOOP FETCH r BULK COLLECT INTO l_data LIMIT 1000; FOR j IN 1 .. l_data.COUNT LOOP l_data(1).part_num := l_data(1).part_num * 10; END LOOP; FORALL i IN 1..l_data.COUNT INSERT INTO child VALUES l_data(i); EXIT WHEN r%NOTFOUND; END LOOP; COMMIT; CLOSE r; END fast_way; / -- 0.50 seconds SARCASM Oh my gawd my fingers are killing me. All the heavy lifting and hard work. Please excuse me for a minute. I need to sit down and catch my breath ... make an appointment to have my carpel tunnel syndrome treated ... make out my will. And all I did was speed the code up by a lousy 15.42 times. Hardly worth it eh. /SARCASM Good thing the web is near anonymous Ken. You might have just talked yourself out of quite a few job opportunities if recruiters look for you on the web. A few microseconds my .... |
#10
| |||
| |||
|
|
On Nov 1, 3:49 pm, DA Morgan <damor... (AT) psoug (DOT) org> wrote: Ken Denny wrote: On Nov 1, 11:26 am, DA Morgan <damor... (AT) psoug (DOT) org> wrote: Now my examples does not include a cursor loop. But if you have DMBS_ERRLOG then you are in a version of Oracle more recent than 8i. And that means you've no reason for ever writing a cursor loop: Ever! It can save you a lot of typing. Is it worth an extra 1000 keystrokes in code to save one or two microseconds in execution time? Lets see ... with cursor loop. CREATE OR REPLACE PROCEDURE slow_way IS BEGIN FOR r IN (SELECT * FROM parent) LOOP -- modify record values r.part_num := r.part_num * 10; -- store results INSERT INTO child VALUES (r.part_num, r.part_name); END LOOP; COMMIT; END slow_way; / -- 7.71 seconds without cursor loop. CREATE OR REPLACE PROCEDURE fast_way IS TYPE myarray IS TABLE OF parent%ROWTYPE; l_data myarray; CURSOR r IS SELECT part_num, part_name FROM parent; BEGIN OPEN r; LOOP FETCH r BULK COLLECT INTO l_data LIMIT 1000; FOR j IN 1 .. l_data.COUNT LOOP l_data(1).part_num := l_data(1).part_num * 10; END LOOP; FORALL i IN 1..l_data.COUNT INSERT INTO child VALUES l_data(i); EXIT WHEN r%NOTFOUND; END LOOP; COMMIT; CLOSE r; END fast_way; / -- 0.50 seconds SARCASM Oh my gawd my fingers are killing me. All the heavy lifting and hard work. Please excuse me for a minute. I need to sit down and catch my breath ... make an appointment to have my carpel tunnel syndrome treated ... make out my will. And all I did was speed the code up by a lousy 15.42 times. Hardly worth it eh. /SARCASM Good thing the web is near anonymous Ken. You might have just talked yourself out of quite a few job opportunities if recruiters look for you on the web. A few microseconds my .... Sorry. I didn't mean to imply that the savings was never more than a few microseconds. There are many times where the savings using bulk collect and avoiding cursor loops are enormous. What I meant to say was that *SOMETIMES* the savings are minimal while the increase in keystrokes are huge. Consider in your example if your insert had to reference 100 or more individual columns and your parent table had no more than 100 rows. And I still don't buy it. |
![]() |
| Thread Tools | |
| Display Modes | |
| |