If you have a habit, as I do, to quickly check
dba_segments to make sure there is nothing important in the tablespace you are about to drop then deferred segment creation can present some surprises.
Consider the following:
SQL> create tablespace test;
Tablespace created
SQL> create table t (n number) tablespace test;
Table created
SQL> select segment_created from user_tables where table_name='T';
SEGMENT_CREATED
---------------
NO
SQL> select * from dba_segments where tablespace_name='TEST';
no rows selected
I can now go ahead and drop the tablespace. Since there isn't really any segment Oracle allows me to do that without issuing any warnings:
SQL> drop tablespace test;
Tablespace dropped
The weird part comes when you want to do something with that table:
SQL> insert into t values (1);
insert into t values (1)
ORA-00959: tablespace 'TEST' does not exist
SQL> alter table t move tablespace users;
alter table t move tablespace users
ORA-00959: tablespace 'TEST' does not exist
SQL> drop table t;
drop table t
ORA-00959: tablespace 'TEST' does not exist
The most annoying part is that you can't move or even drop the table and I see no real reason for such behavior. After all, if Oracle allows you to drop the tablespace pretending that nothing is there, it should allow me to drop/change storage parameters for a non existing segment as well. Otherwise it looks like the "front end" got updated to support deferred segment creation while the "back end" still operates the legacy way. Thankfully there is an easy workaround -- just create a shell tablespace with required name and then move the table:
SQL> create tablespace test;
Tablespace created
SQL> alter table t move tablespace users;
Table altered
Best example I've ever seen of the left hand not knowing what the right hand is doing. And the sad story of Oracle "new feature" management of the last 10 years...
ReplyDeleteThank you for pointing that out that little pitfall and also for showing the workaround!
ReplyDelete