該文主要介紹分區表如何與一般表進行交換資料,在交換中遇到的幾個問題及解決。
實驗需要的表及資料
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。