Error in v$sql.rows_processed. 1,000,000 rows per second
I am running oracle 9i on a Unix box ( 32 bit )
I have a small pl/sql procedure that uses a database link in the cursor and a commit command in the body. When I monitor the value of v$sql.rows_processed, that number increases about 1,000,000 rows per second until it reaches the maximum value for a pls_integer, 2,147,483,647 and then it becomes negative 2,147,483,647. The row count increases until it passes zero and then, +2,147,483,647. This cycle will continue based on the number of rows in the queried table (users).
I am looking for a reason this takes place and I have four concerns. What is the actual number of rows I am processing, I do not want a cartesian situation. Does this take place in 10G. Is there a work around. Should I be concerned about the accuracy of the v$ tables.
I posted an SR (TAR 5015075.993) with Oracle on Jan 3 but they have not offered any help.
Thanks, Eric
---------------- The procedural code ------------------
Code:
CREATE OR REPLACE PROCEDURE update_monthly_age
IS
UID monthly_age.userid%TYPE;
uage monthly_age.months%TYPE;
utab INTEGER;
dtab INTEGER;
sql_string VARCHAR2 ( 200 ) := '';
CURSOR c1
IS
SELECT userid,
age
FROM users@pidm_ltus25d;
BEGIN
OPEN c1;
LOOP
FETCH c1
INTO UID,
uage;
EXIT WHEN c1%NOTFOUND;
uage := uage
* 12;
sql_string := 'update monthly_age set months = '
|| uage
|| ' where userid = '
|| UID;
utab := DBMS_SQL.open_cursor;
DBMS_SQL.parse ( utab,
sql_string,
DBMS_SQL.v7
);
dtab := DBMS_SQL.EXECUTE ( utab );
DBMS_SQL.close_cursor ( utab );
COMMIT;
END LOOP;
CLOSE c1;
END update_monthly_age;
/
---------------- Oracle Version Information --------------
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
PL/SQL Release 9.2.0.4.0 - Production
CORE 9.2.0.3.0 Production
TNS for Solaris: Version 9.2.0.4.0 - Production
LSRTL Version 9.2.0.4.0 – Production
Gandolf989, DaPi, Gamyes; checked on your suggestions
To Gandolf989, DaPi, Gamyes;I looked at your suggestions and put my comments below. This is still a problem. Could anyone try this is one of your databases?
-- in the remote database
create table well ( entity varchar2(20) , country varchar2(12), province_state varchar2(12));
insert into well select to_char ( object_id ) , 'USA' , '42' from dba_objects where rownum < 10001;
To: Gandolf989. This morning I reran this job in three different data that were taken down for backups over the weekend. To look at your idea of a cartesian join/situtation, I changed the query against v$sql to just "select rows_processed , substr ( sql_text , 1 , 75 ) from v$sql. I am still seeing this absurd number of records processed. In a 10 minute test v$sql said that I processed almost 4 Billlion rows. I have not tried tk_prof yet.
To DaPi: You are totally correct regarding your comments on the lack of the cursor and the construction of the update statements. The original code is 200-300 lines and really does not make any sense to post. This was the smallest example that I could post. In honesty, this problem takes place WITHOUT the update statement and the sql_string assignment but, I put them in to make the example have some meaning. (Please see my new example below; I know the cursor is different but that does not seem to matter). If I move the commit to outside the loop in the cursor, get_well_number, everything works correctly. I need the commit statement because I am processing from 0 to 50,000 rows in the cursor in my code. My appologies on TEXAS and OHIO, that is an earlier example that I did not post.
-------------------------------------------
Code:
CREATE OR REPLACE PROCEDURE gather_well_codes
IS
n NUMBER := 1;
c_code well.entity%TYPE;
-- Arrays
TYPE wcode IS TABLE OF well.entity%TYPE
INDEX BY BINARY_INTEGER;
w_code wcode;
-- Fetch entity for wells in Texas (state code=42)
CURSOR get_well_numbers
IS
SELECT entity
FROM well@pidm_ltus25d
WHERE country = 'USA'
AND province_state = '42';
BEGIN
n := 0;
OPEN get_well_numbers;
LOOP
FETCH get_well_numbers
INTO c_code;
EXIT WHEN get_well_numbers%NOTFOUND;
n := n
+ 1;
COMMIT;
END LOOP;
CLOSE get_well_numbers;
END gather_well_codes;
/
--------------------------------------------------
To Gamyers: I agree with you suggestion for improving the code. Please read what I mentioned to DaPi, just above the example of code in this reply.
Thanks for your ideas. This is such a simple piece of code it is driving me nuts.