碰到一個有意思的問題,如果分區表執行過SET UNUSED操作,那么是否還可以進行分區的EXCHANGE操作。
一個簡單的測試就可以說明這個問題:
SQL> create table t_part_unused
2 (id number, name varchar2(30), other varchar2(30))
3 partition by range (id)
4 (partition p1 values less than (10),
5 partition pmax values less than (maxvalue));
Table created.
SQL> insert into t_part_unused
2 select rownum, table_name, 'abc'
3 from user_tables;
48 rows created.
SQL> commit;
Commit complete.
SQL> alter table t_part_unused set unused (other);
Table altered.
SQL> desc t_part_unused
Name Null? Type
---------------------------------------- -------- ------------------------
ID NUMBER
NAME VARCHAR2(30)
SQL> create table t_temp_unused as
2 select *
3 from t_part_unused
4 where 1 = 2;
Table created.
SQL> desc t_temp_unused
Name Null? Type
---------------------------------------- -------- ------------------------
ID NUMBER
NAME VARCHAR2(30)
SQL> alter table t_part_unused
2 exchange partition p1
3 with table t_temp_unused;
with table t_temp_unused
*
ERROR at line 3:
ORA-14097: column type or size mismatch in ALTER TABLE EXCHANGE PARTITION TB
SQL> alter table t_temp_unused add (other varchar2(30));
Table altered.
SQL> alter table t_part_unused
2 exchange partition p1
3 with table t_temp_unused;
with table t_temp_unused
*
ERROR at line 3:
ORA-14096: tables in ALTER TABLE EXCHANGE PARTITION must have the same number of columns
SQL> alter table t_temp_unused set unused (other);
Table altered.
SQL> alter table t_part_unused
2 exchange partition p1
3 with table t_temp_unused;
Table altered.
很明顯執行了SET UNUSED操作后的表,和普通的表是存在區別的,這種區別導致要求進行EXCHANGE的表必須同樣執行SET UNUSED操作,否則就無法執行EXCHANGE的操作。
當目標表中不包含SETE UNUSED的列時,EXCHANGE操作會出現ORA-14097的錯誤,而如果把列添加到目標表,則會報錯ORA-14096,必須在目標表同樣對列執行SET UNUSED操作,才能通過EXCHANGE之前的檢查。
其實這也不難理解,執行SET UNUSED命令后,數據字典雖然發生了改變,但是表上的數據并沒有刪除,而EXCHANGE操作只是將兩個段的數據字典進行互換,因此如果目標表上缺少SET UNUSED列,是無法執行EXCHANGE操作的。
解決問題的方法有兩個,第一個就是例子中展示的可以在目標表上建立列然后同樣的執行SET UNUSED操作;另外的一個方法就是對于SET UNUSED列執行DROP COLUMN操作,徹底刪除該列。