Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
Database Servers
DB2InformixIngresMS SQLOraclePervasive.SQLPostgreSQLProgressSybase
Desktop Databases
FileMakerFoxProMS AccessParadox
General
General DB TopicsDatabase Theory
Related Topics
Java Development.NET DevelopmentVB DevelopmentMore Topics ...

Database Forum / Oracle / Oracle Server / December 2005

Tip: Looking for answers? Try searching our database.

Very strange problem.

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Scarab - 28 Dec 2005 01:17 GMT
Hi,
Something strange happened to me:

declare
v_rowid varchar(18);
cursor icur is
select rowid from itest
where (idate < SYSDATE - 30);
begin
    open icur;
    loop
        fetch icur into v_rowid;
        exit when icur%NOTFOUND;
        delete from itest where rowid = v_rowid;
        if (mod(icur%ROWCOUNT,3000) = 0) then
           commit;
        end if;
    end loop;
    close icur;
    commit;
end;

I use the above sql to delete some data from table itest, but after execute
the sql, I use
select * from itest where (idate < SYSDATE - 30);
There are still some records that not deleted. What's wrong?
After running the SQL again and again, all the records can be deleted.
By the way, table itest is accessed very frequently, updating and inserting
all the time.
Thanks.
Mark C. Stock - 28 Dec 2005 02:26 GMT
> Hi,
> Something strange happened to me:
[quoted text clipped - 28 lines]
> all the time.
> Thanks.

SYSDATE includes time to the seconds, if idate does too, then you have a
moving target -- every iteration addresses a different time slice

++ mcs
Mark D Powell - 28 Dec 2005 02:51 GMT
Scarab, I suspect your problem has to do with the fact that idate is an
Oracle date datatype and as such it also includes time.  That means
your query does not affect all rows for a specific date, as in day of
the month, the same since depending on when the query runs rows some
rows for a day will test true and some will test false.  That is if the
query time is 9 AM then any row on the same day that has a time value
greater than 9 AM will not be included in the result set.

Try where ( idate < trunc(sysdate - 30) )

This will treat all date values for the cutoff date the same, that is,
time values of 00:00:00 - 23:59:59 will all test true in the where
clause.

The other potential problem you have has to the with the Oracle read
consistency model and how inserts, updates, and deletes are done in
this table.  It is not wise to use rowid values fetched in non-select
for update cursors to peform update or delete operations if concurrent
delete operations exist, without specifying additional selection
criteria.  User A selects a list of rows to be processed without
locking them.  User B deletes row 60 and commits.  Now user B or C
inserts a new row and commits.  The space was available at rowid 60 so
Oracle reuses it.  Now session A gets around to rowid 60 and issues a
delete by rowid.  This is not the same row that was fetched by the
driving cursor.  Whenever concurrent deletes are possible then before
doing a delete or update by rowid you should verify that the row still
meets the selection criteria.  In your example the idate would need to
still be < trunc(sysdate) - 30.  If on update or delete the additional
criteria fails then no action is taken, that is, the delete or update
would not affect any rows.  This is not considered an error by Oracle
and processing would continue.

HTH -- Mark D Powell --
Giridhar - 28 Dec 2005 05:19 GMT
Hi,
I have a doubt whether we can have a cursor on the table and open the
cursor to delete data
from the same table. Will it not cause "snapshot too old error" (1555
Error)?

Thanks,
Giridhar Kodakalla
Scarab - 28 Dec 2005 06:53 GMT
Giridhar,
My Oracle is 8.1.7, I delete records according to rowid, It work for me. I
recall your case is also possible, I have ever seen such a case, but the
error message is not : snapshot too old error, but others which I can't
remember.

Thanks

"Giridhar" <gkodakalla@gmail.com> wrote in message
news:1135747171.889177.308550@o13g a 2000cwo.googlegroups.com...
> Hi,
> I have a doubt whether we can have a cursor on the table and open the
[quoted text clipped - 4 lines]
> Thanks,
> Giridhar Kodakalla
Scarab - 28 Dec 2005 07:38 GMT
OK, Thanks for your wonderful reply, that's the problem.
And I have some other puzzles:
Can I use "for update" in the declaration of a cursor?
cursor icur is
select rowid from itest
where (idate < SYSDATE - 30) for update;

If it can:
1. it will only lock the records that fit the criteria and have
nothing to do with the other records, is it right?
2. When I commit records after delete 3000 rows,
   if (mod(icur%ROWCOUNT,3000) = 0) then
      commit;
  The cursor is no longer usable because the commit operation, how to
workaroud it?

Thank you very much.

> Giridhar,
> My Oracle is 8.1.7, I delete records according to rowid, It work for me. I
[quoted text clipped - 14 lines]
> > Thanks,
> > Giridhar Kodakalla
Sybrand Bakker - 28 Dec 2005 09:06 GMT
>OK, Thanks for your wonderful reply, that's the problem.
>And I have some other puzzles:
[quoted text clipped - 13 lines]
>
>Thank you very much.

1 Please stop top-posting.
2 for update is allowed in a cursor declaration
3 only affected records are locked
4 you don't need to commit in a loop. In Oracle 9i, just set your
undo_retention_time appropiately. If this is a disk space issue, buy
more disks.

--
Sybrand Bakker, Senior Oracle DBA
Scarab - 29 Dec 2005 03:14 GMT
Thanks for your reply, here comes my sp:

create or replace procedure clitest
as
 v_rowid varchar(18);
 msg varchar2(256);
cursor icur is
select rowid from itest
where (idate < SYSDATE - 30) for update nowait;
begin
    open icur;
    loop
        fetch icur into v_rowid;
        exit when icur%NOTFOUND;
        delete from itest where rowid = v_rowid ;
        if (mod(icur%ROWCOUNT,1000) = 0) then
           commit;
        end if;
    end loop;
    close icur;
    commit;
    exception when others then
         rollback;
         msg := 'err:'||substr(sqlerrm, 1, 90);
         insert into sm_err_msg(e_date, e_msg) values (sysdate, msg);
         commit;
end;

Because the number of record is very large, so I want to commit every 1000
rows, but after commit for the first time, the cursor is not availible any
more because of the for update clause in the cursor.

How to workaround it? Thanks.

> >OK, Thanks for your wonderful reply, that's the problem.
> >And I have some other puzzles:
[quoted text clipped - 23 lines]
> --
> Sybrand Bakker, Senior Oracle DBA
Sybrand Bakker - 29 Dec 2005 06:44 GMT
>Because the number of record is very large, so I want to commit every 1000
>rows, but after commit for the first time, the cursor is not availible any
>more because of the for update clause in the cursor.
>
>How to workaround it? Thanks.

You didn't read my reply, did you? If so, why do you continue
top-posting, and why don't you follow up on my suggestions?

As you insist on being rude, I will not reply to any of your questions
in the future.

--
Sybrand Bakker, Senior Oracle DBA
Scarab - 29 Dec 2005 07:10 GMT
I am so sorry for enraging you. I really feel very sorry for my mistake. I
know you have reminded me for more than one times.
actually, I am a rookie in newsgroup and I don't know exactly what is the
meaning of : top-posting.

Can I bother you to explain it to me? I will never err in it again.

Thank you very much.

> >Because the number of record is very large, so I want to commit every 1000
> >rows, but after commit for the first time, the cursor is not availible any
[quoted text clipped - 10 lines]
> --
> Sybrand Bakker, Senior Oracle DBA
Sybrand Bakker - 29 Dec 2005 09:33 GMT
>Can I bother you to explain it to me? I will never err in it again.

Rhetorical question: did you learn to read from bottom to top?
Do you know the difference between bottom and top at all?
Or are you just too lazy to hit a key to get at the end of the
previous message?
If I recall correctly, the concept of top-posting has been already
explained several times to you. Please do not pretend you didn't
understand the explanation! Please don't post insincere apologies!
It is quite clear you just don't care.
As you also ignore every advice that doesn't suit you.
As you already know everything better, why do you ask advice here?

--
Sybrand Bakker, Senior Oracle DBA
Scarab - 30 Dec 2005 00:57 GMT
> >Can I bother you to explain it to me? I will never err in it again.
>
[quoted text clipped - 11 lines]
> --
> Sybrand Bakker, Senior Oracle DBA

I am really very sorry to make such a mistake, and I must apologize for all
inconvenience I brought to you, I want to say: it is not insincere.
I think I understand what top-posing  means till now.
Thank you any way.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2010 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.