Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Cursor ORDER BY Clause Changing Row Count In BULK COLLECT ... FOR LOOP?

711096Jul 9 2009 — edited Jul 9 2009
Oracle 10g Enterprise Edition Release 10.2.0.4.0 running on Windows Server 2003
Oracle Client 10.2.0.2.0 running on Windows 2000

I have some PL/SQL code that's intended to update a column in a table based on a lookup from another table. I started out by testing it with the UPDATE statement commented out, just visually inspecting the DBMS_OUTPUT results to see if it was sane. During this testing I added/changed the cursor ORDER BY clause to make it easier to read the output, and saw some strange results. I've run the code 3 times with:

1. no ORDER BY clause
2. ORDER BY with two columns (neither indexed)
3. ORDER BY with one column (not indexed)

and get three different "rows updated" counts - in fact, when using the ORDER BY clauses it appears that the code is processing more rows than without either ORDER BY clause. I'm wondering why adding / changing an ORDER BY <non-indexed column> clause in a cursor would affect the row count?

The code structure is:

-----

TYPE my_Table_t IS TABLE OF table1%ROWTYPE ;
my_Table my_Table_t ;
CURSOR my_Cursor IS SELECT * FROM table1 ; -- initial case - no ORDER BY clause
-- ORDER BY table1.column1, table1.column2 ; -- neither column indexed
-- ORDER BY table1.column2 ; -- column not indexed

my_Loop_Count NUMBER := 0 ;

OPEN my_Cursor ;

LOOP

FETCH my_Cursor BULK COLLECT INTO my_Table LIMIT 100 ;
EXIT WHEN my_Table.COUNT = 0 ;

FOR i IN 1..my_Table.COUNT LOOP

my_New_Value := <call a pkg.funct to retrieve expected value from another table> ;
EXIT WHEN my_New_Value IS NULL ;
EXIT WHEN my_New_Value = <an undesirable value> ;

IF my_New_Value <> my_Table(i).column3 THEN
DBMS_OUTPUT.PUT_LINE( 'Changing ' || my_Table(i).column3 || ' to ' || my_New_Value ) ;
/*****
UPDATE table1 SET column3 = my_New_Value WHERE column_pk = my_Table(i).column_pk ;
*****/
my_Loop_Count := my_Loop_Count + 1 ;
END IF ;

END LOOP ;

COMMIT ;

END LOOP ;

CLOSE my_Cursor ;

DBMS_OUTPUT.PUT_LINE( 'Processed ' || my_Loop_Count || ' Rows ' ) ;
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Aug 6 2009
Added on Jul 9 2009
7 comments
886 views