碰到一个有意思的问题,如果分区表执行过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操作,彻底删除该列。