該文主要介紹分區表如何與一般表進行交換數據,在交換中遇到的幾個問題及解決。
實驗需要的表及數據
create table t_addr
(
id NUMBER(18) PRIMARY KEY,
name VARCHAR2(300),
tag NUMBER
)
partition by list (tag)
(
partition P_AREA1 values (1),
partition P_AREA2 values (2),
partition P_AREA3 values (3),
partition P_AREA_DEFAULT values (DEFAULT));
INSERT INTO t_addr SELECT o.OBJECT_ID,o.OBJECT_NAME,1 FROM dba_objects o;
alter table t_addr enable row movement;
UPDATE t_addr SET tag=1;
UPDATE t_addr SET tag=2 WHERE ROWNUM<=50000;
UPDATE t_addr SET tag=3 WHERE ROWNUM<=40000;
UPDATE t_addr SET tag=5 WHERE ROWNUM<=10000;
BEGIN dbms_stats.gather_table_stats('kgis','t_addr');END;
CREATE TABLE tmp_addr AS SELECT * FROM t_addr WHERE 1=0;
交換的語句:
alter table t_addr
exchange partition P_AREA2
with table tmp_addr
including indexes
without VALIDATION
UPDATE GLOBAL INDEXES;
UPDATE GLOBAL INDEXES --這個語句是針對全局索引,如果分區表有全局索引加上該語句就不會失效,否則交換后全局索引會無效需重建
交換表:tmp_addr
分區表:t_addr
ORA-14097: ALTER TABLE EXCHANGE PARTITION 中的列類型或大小不匹配
原因:交換表與要交換分區的表結構要一致,如分區表(t_addr)id是主鍵,那么交換表(tmp_addr)的id也必須有主鍵。
ALTER TABLE tmp_addr ADD PRIMARY KEY(ID)增加后在執行交換就成功了。
分區表創建的主鍵默認為全局索引,那么交換表對應的字段也需要創建主鍵;而且不能包含索引交換
(including INDEXES without VALIDATION)。
總結:如果分區表含有主鍵,那么交換表相應字段也必須有主鍵;
而且交換時不能包含索引,否則也會報ORA-14098錯誤,即只能交換數據。
ORA-14098: ALTER TABLE EXCHANGE PARTITION 中的表索引不匹配
原因:
1.如果分區表的非分區健創建了本地索引,那么交換表的該字段就也必須創建索引,否則報如上該錯誤,如下例子所示:
create index idx_addrid on t_addr(ID) LOCAL;
create index idx_tmpid on tmp_addr(ID);
alter table t_addr
exchange partition P_AREA2
with table tmp_addr
including indexes
without VALIDATION
交換成功
DROP INDEX idx_tmpid;
alter table t_addr
exchange partition P_AREA2
with table tmp_addr
including indexes
without VALIDATION
刪除交換表的索引交換報如上錯誤。
2.如果分區表的非分區健創建了全局索引,那么交換表的該字段就不能創建索引,否則報如上該錯誤,如下例子所示:
DROP INDEX idx_addrid;
create index idx_addrid on t_addr(ID);
create index idx_tmpid on tmp_addr(ID);
alter table t_addr
exchange partition P_AREA2
with table tmp_addr
including indexes
without VALIDATION
進行交換報如上錯誤。
DROP INDEX idx_tmpid
alter table t_addr
exchange partition P_AREA2
with table tmp_addr
including indexes
without VALIDATION
刪除索引后交換成功。
注:1和2的測試時,分區健tag在分區表創建的是本地索引,交換表也創建了索引,即如下創建語句:
create index idx_addrtag_local on t_addr(tag) LOCAL
create index idx_tmptag_ on tmp_addr(tag)
3.如果分區表的分區健創建了本地索引,那么交換表的該字段也必須創建索引
將id字段的索引刪除:
DROP INDEX idx_addrid;--刪除分區表的id字段的全局索引,注意交換表的該字段索引也已經刪除
現在索引情況是:分區表的分區健為本地索引,交換表對應的該字段也創建了索引,執行交換沒有問題。
如果將交換表的該字段索引刪除,則報如上錯誤:
DROP INDEX idx_tmptag_;
alter table t_addr
exchange partition P_AREA2
with table tmp_addr
including indexes
without VALIDATION
4.如果分區表的分區健創建了全局索引, 交換表的該字段就不能創建索引,否則報如上錯誤
DROP INDEX idx_addrtag_local;
create index idx_addrtag_local on t_addr(tag);--分區健創建全局索引
--交換表該字段無索引交換成功
alter table t_addr
exchange partition P_AREA2
with table tmp_addr
including indexes
without VALIDATION
create index idx_tmptag_ on tmp_addr(tag);
--交換表該字段也創建索引執行交換報如上錯誤
alter table t_addr
exchange partition P_AREA2
with table tmp_addr
including indexes
without VALIDATION
總結:如果交換時包含索引,不管分區健還是非分區健,如果分區表創建的是分區索引,則交換表相應字段也必須創建索引;
如果分區表創建了全局索引,則交換表相應字段就不能創建索引,否則報ORA-14098錯誤。
ORA-02266: 表中的唯一/主鍵被啟用的外部關鍵字引用
原因:分區表中的主鍵被別的表引用,因此執行交換前必須先把該主鍵disable及引用該主鍵的外鍵disable,同時
交換表中的主鍵也必須disable掉與分區表保持一致。
--對分區表即交換表的主鍵及引用該主鍵的外鍵disable
alter table partiton_tablename disable primary key cascade;--加上cascade后引用該主鍵的外鍵也會disable
alter table change_tablename disable primary key cascade;
注:由於將主鍵disable了,因此交換后記得將主鍵及引用該主鍵的外鍵enable。