Tip

Avoid 'cannot extend rollback segment' error when deleting rows

You can delete as many rows as you like without having to worry about RBS size. One method is very low-tech:

Delete from tbl_x where rownum < 1000
Then run it as many times as you need to delete all the rows.

The other method is more sophisticated and flexible. Build a cursor to select the rows you want to delete and then in an anonymous PL/SQL block, loop through the cursor, and delete one row at a time. Keep track of the number of rows processed, and after a predetermined limit, commit the records deleted to that point. (I believe that the best performance can be obtained if you retrieve the row_id in the cursor and sort by row_id. This allows you to do a full table scan and only touch a block once, during the execution of the program.)

The program below was modified to remove sensitive information, but the basic structure is intact. I accidentally removed the code that checks for what mode you are running in (update/read-only) but you should be able to figure it out. Since I hate getting code that doesn't work, I tested it after the mods, and it still runs on Oracle 8.1.7.

-- turn on printing
set serveroutput on size 999999;

-- display start/end time + instance name
Select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') "Start Date / Time",
       substr(vi.host_name,1,15) "Host", vi.instance_name "Instance",
       vd.name "Dbname",substr(User,1,12) "User",
       vd.created "Instance Created", chr(13), chr(10)from Dual, V$Database vd, v$instance vi ;


-- The real work is done here
declare
        tc_num       number(6)    := 0;  -- counter for # of recs read
        COMMIT_COUNT number(6)    := 0;  -- count # of recs that have not yet been committed

        vc_Processing_Mode  varchar2(9) := 'READ-ONLY';
        vc_Commit_Mode      varchar2(9) := 'NO COMMIT';
        vc_var_out   varchar2(41) := 'Pr_PUB_XrefLog Delete Program #1';

        cursor csr_TD is
                select
                       Division,
                       rowid
                  from table_1

                  where division in ('ABc', 'Def')

                 order by   rowid,
                      Division
                                         ;

begin

        dbms_output.put_line(vc_var_out||' Beginning');
        dbms_output.put_line('Running in '||vc_processing_Mode||'with '||vc_commit_mode||'s');

        For csr_TD_Rec in csr_TD    Loop

            tc_num := tc_num + 1 ;
            COMMIT_COUNT := COMMIT_COUNT + 1 ;


            Delete from table_1    T

                  where   T.rowid = csr_td_rec.rowid ;

            IF COMMIT_COUNT >

    Requires Free Membership to View

1000 THEN COMMIT; COMMIT_COUNT := 1; dbms_output.put_line('COMMIT AT..'|| tc_num); END IF; End Loop; IF vc_COMMIT_Mode = 'COMMIT' THEN commit; END IF; dbms_output.put_line(vc_var_out||' Finished'); dbms_output.put_line('Records processed........'|| to_char(tc_num,'999999') ); end; --Select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') "END Date / Time", -- substr(vi.host_name,1,15) "Host", vi.instance_name "Instance", -- vd.name "Dbname",substr(User,1,12) "User", -- vd.created "Instance Created", chr(13), chr(10)from Dual, V$Database vd, v$instance vi ;

Reader Feedback

Jim L. writes: Good tip. The script included in this tip, should always be ordered by rowid to reduce ORA-01555 (snapshot too old errors). It could still conceivably fall over with the dreaded ORA-01555, if there are any migrated rows or indexes involved. To ensure this does not happen then I would close and reopen the cursor after every commit.

For More Information

  • Feedback: E-mail the editor with your thoughts about this tip.
  • More tips: Hundreds of free Oracle tips and scripts.
  • Tip contest: Have an Oracle tip to offer your fellow DBAs and developers? The best tips submitted will receive a cool prize -- submit your tip today!
  • Ask the Experts: Our SQL, database design, Oracle, SQL Server, DB2, metadata, and data warehousing gurus are waiting to answer your toughest questions.
  • Forums: Ask your technical Oracle questions--or help out your peers by answering them--in our active forums.
  • Best Web Links: Oracle tips, tutorials, and scripts from around the Web.

This was first published in April 2003

Join the conversationComment

Share
Comments

    Results

    Contribute to the conversation

    All fields are required. Comments will appear at the bottom of the article.

    Disclaimer: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.