分區表的分區與普通表交換的一些問題

前幾天想要用分區交換的方法將分區表的數據交換出去,結果有的分區交換成功了,有的確失敗了。按照網上說的方法也沒有很好的解決。

這個技術本來應該是一個很方便的技術的,可是由於不太會用,覺得不是很方便。

轉載一篇不錯的博客,以備查用。

http://www.cnblogs.com/lanzi/archive/2013/01/24/2875838.html


該文主要介紹分區表如何與一般表進行交換數據,在交換中遇到的幾個問題及解決。

實驗需要的表及數據
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。
 
發佈了47 篇原創文章 · 獲贊 8 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章