lobs do not generate significant undo. Lobs are versioned in the lob tablespace. The undo would be for the lob index only.
ops$tkyte%ORA10GR2> create table t
2 as
3 select *
4 from all_objects;
Table created.
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> delete from t;
50171 rows deleted.
ops$tkyte%ORA10GR2> select used_ublk from v$transaction;
USED_UBLK
----------
1441
<b>no lob, needs 1441 blocks</b>
ops$tkyte%ORA10GR2> commit;
Commit complete.
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> insert /*+ append */ into t select * from all_objects;
50162 rows created.
ops$tkyte%ORA10GR2> alter table t add c clob;
Table altered.
ops$tkyte%ORA10GR2> declare
2 l_data long := rpad('*',32000,'*');
3 begin
4 update t set c = l_data;
5 commit;
6 end;
7 /
PL/SQL procedure successfully completed.
ops$tkyte%ORA10GR2> select sum(dbms_lob.getlength(c)), count(*) from t;
SUM(DBMS_LOB.GETLENGTH(C)) COUNT(*)
-------------------------- ----------
1605184000 50162
<b>so, that is 1.3GB of lob data...</b>
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> delete from t;
50162 rows deleted.
ops$tkyte%ORA10GR2> select used_ublk from v$transaction;
USED_UBLK
----------
2905
<b>That isn't enough undo blocks to hold 1.3gb - you'd need about 200,000 undo blocks for that (8k blocks as I have)</b>
ops$tkyte%ORA10GR2> commit;
Commit complete.
You can in fact do this without using procedural code.
We call it "sizing your system for what you actually do"
disk is cheap
your time is not
writing code is introducing bugs
bugs cost $$$$$$$
code has to be maintained
less code = less bugs
I will not budge from that position. If your undo configuration is undersized for what you do - you do not change what you do, you size your undo correctly.
you want fast?
you want the least amount of undo generated?
you want the least amount of redo generated?
you want the best index structures in place after the operation?
then you will use precisely two statements, insert+delete.