Oracle have been telling us to convert to lob's since 8.0, but finally in 9i there is a very nice tool to convert LONG/LONG RAW to the new LOB datatypes. You can now simply issue "alter table (longcol CLOB)" to perform the conversion. On the surface, this seems a neat trick, but be aware of the space implications before attempting a conversion.
Here is a simple example to demonstrate the issue:
--
-- First a very small tablespace so we can monitor temporary space requirements
--
SQL> create tablespace tiny
2 datafile 'G:\ORA9I\ORADATA\DB9\TINY.DBF' size 2M
3 extent management local uniform size 64k;
Tablespace created.
--
-- Then we'll let it grow in 256k increments if required
--
SQL> alter database datafile 'G:\ORA9I\ORADATA\DB9\TINY.DBF' autoextend on next 256k;
Database altered.
SQL> alter user mcdonac default tablespace tiny;
User altered.
--
-- Now a basic table with a LONG, thats just a straight copy (4x over) from DBA_VIEWS
-- (Interestingly the COPY command on this machine NT 9.0.1.2 bombed out which is why
-- I'm using PL/SQL)
--
SQL> create table testlong ( text long );
Table created.
SQL> declare
2 p varchar2(32767);
3 begin
4 for j in 1 .. 4 loop
5 for i in ( select text from dba_views ) loop
6 p := i.text;
7 insert into testlong values (p);
8 end loop;
9 commit;
10 end loop;
11 end;
12 /
PL/SQL procedure successfully completed.
SQL> analyze table testlong estimate statistics;
Table analyzed.
SQL> col bytes format 999,999,999,999
SQL> col name format a60
SQL> set lines 120
SQL> select bytes, name
2 from v$datafile
3 where name like '%TIN%';
BYTES NAME
---------------- ------------------------------------------------------------
6,815,744 G:\ORA9I\ORADATA\DB9\TINY.DBF
SQL> select bytes from user_segments
2 where tablespace_name = 'TINY';
BYTES
----------------
6,553,600
SQL> select NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_ROW_LEN,CHAIN_CNT
2 from user_tables
3 where table_name = 'TESTLONG';
NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_ROW_LEN CHAIN_CNT
---------- ---------- ------------ ----------- ----------
9212 796 3 702 64
--
-- So as you can see, the table in its current form is using about 6.5M of space
-- and the tablespace has grown to match.
--
-- Now we convert that column to a clob
--
SQL> alter table TESTLONG modify ( text clob);
Table altered.
--
-- Notice now that we have some additional segment (as we would expect) and
-- the amount of space used has popped out to about 8M. This seems pretty good
--
SQL> col segment_name format a30
SQL> select segment_name, bytes
2 from user_segments
3 where tablespace_name = 'TINY';
SEGMENT_NAME BYTES
------------------------------ ----------------
TESTLONG 5,701,632
SYS_IL0000031894C00001$$ 65,536
SYS_LOB0000031894C00001$$ 2,228,224
--
-- But here is the "gotcha". If we look at the tablespace, it has grown to 14M
-- so at least temporarily, over double the space was required.
--
SQL> select bytes, name
2 from v$datafile
3 where name like '%TIN%';
BYTES NAME
---------------- ------------------------------------------------------------
14,680,064 G:\ORA9I\ORADATA\DB9\TINY.DBF
Obviously this is a pretty basic example, but I struggled to come up with any combination, for example, disabling/enabling storage inline, having many additional non-LONG columns in the source table, "long" LONGs, "short" LONGs etc that did not require close to double the space.
I'm not saying that this is a bad thing - but its certainly something to remember before leaping onto the CLOB conversion bandwagon.