How To Log a PL/SQL Transaction... [message #249528] |
Wed, 04 July 2007 20:37 |
aimy
Messages: 225 Registered: June 2006
|
Senior Member |
|
|
Hello all..
I have a simple procedure like this..
spool /home/oracle9/MIE/CDR-25JUN2007.lst
CREATE OR REPLACE PROCEDURE P_DEL28SEP2006 as
cursor s1 is SELECT rowid, t.* /*+ parallel(tel_calldtl partition(bl_period_0625),4) */
from tel_calldtl partition(bl_period_0625) t
where year_month_date= '200706'
and bill_period='25' and source in ('SMJ', 'SBH', 'SWK');
i number := 0;
begin
for c1 in s1 loop
delete from TEL_CALLDTL partition(bl_period_0625)
where rowid = c1.rowid;
i := i + 1; -- Commit after every 1000 records
if i > 1000 then
commit;
i := 0;
end if;
end loop;
commit;
end;
/
exec P_DEL28SEP2006;
spool off
So, my question is how do I capture how many rows that have been deleted inside the spool file?
Thank you very much.
|
|
|
|
|
|
|
Re: How To Log a PL/SQL Transaction... [message #249540 is a reply to message #249528] |
Wed, 04 July 2007 23:21 |
aimy
Messages: 225 Registered: June 2006
|
Senior Member |
|
|
OK OK I got it!!!
------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE P_DELOLD as
cursor s1 is SELECT rowid, t.* from loading_log_del t where bill_period=25;
i number := 0;
j number :=0;
begin
for c1 in s1 loop
delete from loading_log_del
where rowid = c1.rowid;
j := j +1;
end loop;
DBMS_OUTPUT.PUT_LINE (j ||' rows have been deleted');
end;
------------------------------------------------------------------------------------------------------------
Thanks anacedent!!
[Updated on: Wed, 04 July 2007 23:44] Report message to a moderator
|
|
|
|
|
|
|
|
|
|
|
Re: How To Log a PL/SQL Transaction... [message #249608 is a reply to message #249528] |
Thu, 05 July 2007 03:16 |
flyboy
Messages: 1903 Registered: November 2006
|
Senior Member |
|
|
Too bad you did not read the second link to its end.
Quote: | Soon after publishing this months DBA Tip, Geurts Maarten wrote in to indicate that the above PL/SQL block may not work where you may have either many processes running on the system or if the table is too large. If you do not have a rollback segment large enough, you may encounter the "snapshot too old" error. This is because the code block is modifing the snapshot the first cursor uses to get its rowids from.
You need to reopen the snapshot.
...
|
Again hitting the rollback segment size.
Moreover it does not say anything about efficiency.
How many rows do you suppose to delete?
How large is your UNDO tablespace?
|
|
|
|
Re: How To Log a PL/SQL Transaction... [message #249612 is a reply to message #249604] |
Thu, 05 July 2007 03:40 |
JRowbottom
Messages: 5933 Registered: June 2006 Location: Sunny North Yorkshire, ho...
|
Senior Member |
|
|
That is a valid solution to the problem of not having enough Rollback/Undo space.
However, you've not mentioned that this has been a problem that you have encountered.
Let's have a nice simple example. We'll create a table, put a hundred thousand rows in it, and try deleting them in one go, and then in 1000 groups with one commit, and delete them in 1000 groups with a commit after each delete.
As the results below show, the single delete took 4.09 seconds, the 1000 deletes with one commit took 17.06 seconds, and the 1000 deletes with individual commits took 20.08 seconds.
SQL> drop table delete_Test;
Table dropped.
SQL> create table delete_test (id_col number,grp number, col_1 varchar2(20));
Table created.
SQL> insert into delete_test select lvl, mod(lvl,1000),'Row '||lvl
2 from (select level lvl from dual connect by level <= 100000);
100000 rows created.
SQL> set timing on
SQL> delete delete_test;
100000 rows deleted.
Elapsed: 00:00:04.09
SQL> commit;
Commit complete.
Elapsed: 00:00:00.00
SQL> set timing off
SQL> insert into delete_test select lvl, mod(lvl,1000),'Row '||lvl
2 from (select level lvl from dual connect by level <= 100000);
100000 rows created.
SQL> set timing on
SQL> begin
2 for rec in (select distinct grp from delete_test) loop
3 delete delete_Test where grp = rec.grp;
4 end loop;
5 commit;
6 end;
7 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:17.06
SQL> set timing off
SQL> insert into delete_test select lvl, mod(lvl,1000),'Row '||lvl
2 from (select level lvl from dual connect by level <= 100000);
100000 rows created.
SQL> set timing on
SQL> begin
2 for rec in (select distinct grp from delete_test) loop
3 delete delete_Test where grp = rec.grp;
4 commit;
5 end loop;
6 end;
7 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:20.08
SQL> set timing off
|
|
|
|
|
|
|
Re: How To Log a PL/SQL Transaction... [message #249672 is a reply to message #249615] |
Thu, 05 July 2007 09:10 |
JRowbottom
Messages: 5933 Registered: June 2006 Location: Sunny North Yorkshire, ho...
|
Senior Member |
|
|
Here's the results from a much more active database - I was still the only one using this table though.
This single delete performs the same, and the multiple deletes are much worse.
SQL> delete delete_test;
100000 rows deleted.
Elapsed: 00:00:04.02
SQL>
SQL> commit;
Commit complete.
Elapsed: 00:00:00.00
SQL>
SQL> set timing off
SQL>
SQL> insert into delete_test select lvl, mod(lvl,1000),'Row '||lvl
2 from (select level lvl from dual connect by level <= 100000);
100000 rows created.
SQL>
SQL> set timing on
SQL>
SQL> begin
2 for rec in (select distinct grp from delete_test) loop
3 delete delete_Test where grp = rec.grp;
4 end loop;
5 commit;
6 end;
7 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:51.02
SQL>
SQL> set timing off
SQL>
SQL> insert into delete_test select lvl, mod(lvl,1000),'Row '||lvl
2 from (select level lvl from dual connect by level <= 100000);
100000 rows created.
SQL>
SQL> set timing on
SQL>
SQL> begin
2 for rec in (select distinct grp from delete_test) loop
3 delete delete_Test where grp = rec.grp;
4 commit;
5 end loop;
6 end;
7 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:55.03
SQL>
SQL> set timing off
SQL>
SQL> drop table delete_test;
Table dropped.
|
|
|
Re: How To Log a PL/SQL Transaction... [message #249742 is a reply to message #249528] |
Thu, 05 July 2007 13:49 |
flyboy
Messages: 1903 Registered: November 2006
|
Senior Member |
|
|
Quote: | No, but If I have to move 40 tons of sand to the other side of a river, and only have a bridge that can support 10 tons, I might make 4 trips instead of building a bigger bridge.
|
Nice analogy, however I would describe the posted approach as moving the sand in a hand-barrow .
If aimy would read the second article to its very end (I did not posted it here), he would find a solution combining multi-row delete (not row-by-row as processed now) with intermediate commits. Definitely better than the posted one, not causing ORA-01555. I would just increase the commit size, 5000 is still too low.
Quote: | One way to solve this issue is to use the TRUNCATE command.
|
I would think over sub-partitioning on source column (if possible).
|
|
|