12c Create Table for Exchange Partition

以前版本中如果我们要对一个分区表做EXCHANGE PARTITION时,都会通过create table as select * XXX来新建一张普通表用于exchange,但是可能遇到这样的情况,源表的部分字段被禁用或不可见,则会导致exchange的时候失败,原因是因为两个表的表结构不一致。

而在新的12.2版本中,提供了一种新的建表方法,通过FOR EXCHANGE WITH语句来确保做exchange分区操作时的表与分区表形状一致,当然这种建表的方法并不会同步建索引。

下面总结了CREATE TABLE FOR EXCHANGE WITH操作所带来的一些影响:

  • 这个DDL操作主要是为了方便创建用于做exchange partition操作的表

  • 这个操作其实就是对要做exchange表的克隆,包含字段的顺序以及属性

  • 新建的表无法重命名,都是从源表继承下来

  • 这个DDL操作中唯一一个可以改变的逻辑属性是表是否为partition

    比如源表为一个复合分区表,如果多个子分区交换到新表的分区下,这种情形时,你就可以指定新表是否需要为分区表。

    子分区与分区之间可以是非对称的,但是在建表的时候必须要精确匹配分区与子分区的对应关系。

  • 可以指定的物理属性则为表使用的段属性

  • 使用这个DDL操作可以复制的列包括不限于以下:不可用列、不可见列、虚拟列、函数索引表达式列以及其他内部设置和属性

以前版本CTAS

创建一个测试分区表作为源表,包含了几种特殊类型的字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
drop table t1 purge;

create table t1 (
id number,
col1 varchar2(100),
col2 varchar2(100),
col3 generated always as (id+100) virtual
)
partition by range (id)
(
partition p1 values less than (200),
partition p2 values less than (400)
);

create index idx_t1 on t1(id);

分别修改col1和col2的字段属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
xb@PDB12C> alter table t1 set unused(col1);

Table altered.

xb@PDB12C> alter table t1 modify col2 invisible;

Table altered.

xb@PDB12C> @desc t1
Name Null? Type
------------------------------- -------- ----------------------------
1 ID NUMBER >>>>====已经看不到col1和col2两个字段
2 COL3 NUMBER

col column_name for a40
col data_type for a20
col data_length for 999999999999
col data_default for a20
col virtual_column for a20
SELECT column_name, data_type, data_length, data_default, virtual_column
FROM user_tab_cols
WHERE table_name = 'T1';

COLUMN_NAME DATA_TYPE DATA_LENGTH DATA_DEFAULT VIRTUAL_COLUMN
---------------------------------------- -------------------- ------------- -------------------- --------------------
ID NUMBER 22 NO
SYS_C00002_19031410:18:00$ VARCHAR2 100 NO
COL2 VARCHAR2 100 NO
COL3 NUMBER 22 "ID"+100 YES

创建一张新的普通表用来做EXCHANGE PARTITION

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
drop table t2 purge;
create table t2 as select * from t1 where 1=2;
create index idx_t2 on t2(id);

COLUMN_NAME DATA_TYPE DATA_LENGTH DATA_DEFAULT VIRTUAL_COLUMN
---------------------------------------- -------------------- ------------- -------------------- --------------------
ID NUMBER 22 NO
COL3 NUMBER 22 NO >>>>====新表字段并非虚拟列


insert into t2
select level from dual connect by rownum>=200;

commit;

alter table t1
exchange partition p1
with table t2
without validation
update global indexes;

ERROR at line 3:
ORA-14096: tables in ALTER TABLE EXCHANGE PARTITION must have the same number of columns

可以看到报错提示字段数量不一致,CTAS对于这种情况就不太适用。

新版本FOR EXCHANGE WITH

现在可以使用12.2新的语句CREATE TABLE ... FOR EXCHANGE WITH

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
drop table t2 purge;

create table t2
for exchange with table t1;
create index idx_t2 on t2(id);

col column_name for a40
col data_type for a20
col data_length for 999999999999
col data_default for a20
col virtual_column for a20
SELECT column_name, data_type, data_length, data_default, virtual_column
FROM user_tab_cols
WHERE table_name = 'T2';

COLUMN_NAME DATA_TYPE DATA_LENGTH DATA_DEFAULT VIRTUAL_COLUMN
---------------------------------------- -------------------- ------------- -------------------- --------------------
COL2 VARCHAR2 100 NO
SYS_C00002_19031410:18:00$ VARCHAR2 100 NO
ID NUMBER 22 NO
COL3 NUMBER 22 "ID"+100 YES

可以看到现在新建的T2表字段属性就跟T1完全一样,继续剩下的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
insert into t2(id)
select level from dual connect by rownum>=200;

commit;

xb@PDB12C>
alter table t1
exchange partition p1
with table t2
without validation
update global indexes;

Table altered.

xb@PDB12C> select * from t1 partition (p1) where rownum>=10;

ID COL3
---------- ----------
1 101
2 102
3 103
4 104
5 105
6 106
7 107
8 108
9 109
10 110

10 rows selected.

则可以顺利完成分区交换操作。


12c Create Table for Exchange Partition
https://www.xbdba.com/2019/03/14/12c-create-table-for-exchange-partition/
作者
xbdba
发布于
2019年3月14日
许可协议