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%';
--------------- -------------------- ------------------ ---------- ---------- ------ -------
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;
表已更改。
這個操作是比較慢的。。