1. 程式人生 > >oracle表 中刪除一列

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%';

SEGMENT_NAME    PARTITION_NAME      SEGMENT_TYPE       TABLESPACE      BYTES   BLOCKS   EXTENTS
---------------                     --------------------           ------------------               ----------               ----------      ------            -------
T2                                                                               TABLE                    USERS                 2097152    256             17

索引也會一併刪除的。。。。

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

在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;

表已更改。

這個操作是比較慢的。。