天天看點

oracle表 中删除一列

1、測試

在sys使用者下建立測試表:

SQL> create table t  as select object_id,object_name from dba_objects;

表已建立。

SQL> select count(*)from t ;

 COUNT(*)

----------

48940

删除object_name 列:

SQL> alter table t drop column object_name;

alter table t drop column object_name

*

第 1 行出現錯誤:

ORA-12988: cannot drop column from table owned by SYS

我去。。。在sys使用者下面的表是不能删除列的。。。。這下腫麼辦?簡單。。。換個表空間,換個使用者解決:

SQL> create table scott.t2 tablespace users as select  * from t ;

給表建個索引,一會測試用:

SQL> create index i_t1 on t2(object_id);

索引已建立。

 SQL> select segment_name,partition_name,segment_type,tablespace_name,bytes,blocks,extents from user_segments where segment_name like '%T2%' ;

SEGMENT_NAME    PARTITION_NAME      SEGMENT_TYPE       TABLESPACE      BYTES   BLOCKS   EXTENTS

---------------                     --------------------           ------------------               ----------               ----------      ------            -------

I_T2                                                                           INDEX                     USERS                 983040      120             15

T2                                                                               TABLE                    USERS                 2097152    256             17

删除列,需要一段時間,其中會牽涉到表内鎖的鎖定。

SQL> alter table t2 drop column object_id;

表已更改。

再次查詢段結構:

SQL> select segment_name,partition_name,segment_type,tablespace_name,bytes,blocks,extents from user_segments where segment_name like '%T2%';

索引也會一并删除的。。。。

注意:在大表上删除列的時候,一定要注意,它會花費很長的時間,鎖住表,影響資料庫性能。

在oracle資料庫中,還有一種方法用來删除列:

SQL> alter table t2 set unused column object_id;

這條語句的意思是把object_id置為不可用,更改此列的名稱(oracle内部明白),但是不會釋放此列對應的空間。(我測試的時候,如果删除的列時索引列,然後再去找索引就找不到了,查得dba_indexes視圖中的index_name 沒有了,總行數也少了一行。猜測應該是索引也重命名了,已經不是索引了。但是空間估計也不會釋放的。沒有測試。。。)這個執行非常快,和truncate的機制差不多,在生産庫中如果需要緊急應用,為了避免drop column操作鎖住表,可以使用這個語句。等到系統有充足的時間時,我們再用另一個語句來釋放空間:

alter table t2 drop unused columns;

這個操作是比較慢的。。