1. 程式人生 > >ORA-14060: 不能更改表分割槽列的資料型別或長度

ORA-14060: 不能更改表分割槽列的資料型別或長度

在對分割槽表進行改造的時候,出現ORA-14060錯誤。這個原因主要是對分割槽鍵的欄位型別進行了修改(分割槽表中對其他欄位型別的修改沒有問題)。
之前的做法是使用線上重定義,把分割槽表改造成非分割槽表,修改欄位型別,再次線上重定義進行分割槽。
參考MOS 330964.1 ,可以使用alter table exchange partition來做。兩種方法各有利弊 。

步驟
1 建立每個分割槽對應的交換表,有幾個分割槽就建立幾個交換表
2 進行分割槽交換,將各個分割槽內的資料交換到交換表
3 對各個交換表進行修改欄位
4 重新建立分割槽表
5 再次交換,將交換表的資料交換到分割槽表 
6 drop掉交換表 

-- 建立分割槽表

CREATE TABLE emp2
(empno NUMBER(4) NOT NULL,
ename VARCHAR2(10),
sal NUMBER(7))
PARTITION BY RANGE(ename)
(partition emp2_p1 VALUES LESS THAN ('D'),
partition emp2_p2 VALUES LESS THAN ('Q'),
partition emp2_p3 VALUES LESS THAN (MAXVALUE))

-- 插入資料

insert into emp2 values(1,'Andy',575);
insert into emp2 values(2,'Derek',570);
insert into emp2 values(3,'Patrick',590);
insert into emp2 values(4,'Richard',400);
commit;

-- 查詢emp2表,有4條資料

select * from emp2;

-- 檢視各個分割槽表,每個分割槽均有資料

select * from emp2 partition (emp2_p1);
select * from emp2 partition (emp2_p2);
select * from emp2 partition (emp2_p3);

-- 嘗試修改emp2分割槽表的ename欄位 ,因為該欄位是分割槽鍵,所以會報ORA-14060錯誤 

alter table emp2 modify(ename varchar2(10 char))

--建立3個表,用來和分割槽表交換資料 ,

create table emp2_part1
(empno NUMBER(4) NOT NULL,
ename VARCHAR2(10),
sal NUMBER(7));


create table emp2_part2
(empno NUMBER(4) NOT NULL,
ename VARCHAR2(10),
sal NUMBER(7));


create table emp2_part3
(empno NUMBER(4) NOT NULL,
ename VARCHAR2(10),
sal NUMBER(7));

-- 開始交換資料 ,把emp2裡面的資料,交換到臨時的表裡面 emp2_part[1 2 3]裡面 ,emp2裡面沒有資料了 

alter table emp2 exchange partition emp2_p1 with table emp2_part1;  -- 資料到了emp2_part1裡面 
alter table emp2 exchange partition emp2_p2 with table emp2_part2;  -- 資料到了emp2_part2裡面
alter table emp2 exchange partition emp2_p3 with table emp2_part3;  -- 資料到了emp2_part3裡面

-- 重新改造emp2 ,先drop掉emp2,再按照需求建立正確欄位的emp2表.注意之前的表ename欄位是varchar2(10),現在是varchar2(10 char)

DROP TABLE EMP2;

CREATE TABLE emp2
(empno NUMBER(4) NOT NULL,
ename VARCHAR2(10 CHAR),
sal NUMBER(7))
PARTITION BY RANGE(ename)
(partition emp2_p1 VALUES LESS THAN ('D'),
partition emp2_p2 VALUES LESS THAN ('Q'),
partition emp2_p3 VALUES LESS THAN (MAXVALUE));

-- 然後修改emp2_part1 2 3 的ename列型別 。 如果不修改,在進行exchange資料交換的時候,會提示ORA-14097 。

alter table emp2_part1 modify(ename varchar2(10 CHAR));
alter table emp2_part2 modify(ename varchar2(10 CHAR));
alter table emp2_part3 modify(ename varchar2(10 CHAR));

-- 然後exchange資料交換 .emp2_part1 2 3 裡面的資料就到了emp2

alter table emp2 exchange partition emp2_p1 with table emp2_part1;
alter table emp2 exchange partition emp2_p2 with table emp2_part2;
alter table emp2 exchange partition emp2_p3 with table emp2_part3;

-- 然後drop掉臨時的表 emp2——part1 2 3 

drop table emp2_part1;
drop table emp2_part2;
drop table emp2_part3;

END

如果 分割槽表emp2和emp2_part3都有資料,則exchange會怎樣 ?

[email protected]>select * from emp2;

     EMPNO ENAME	     SAL
---------- ---------- ----------
	 1 Andy 	     575
	 2 Derek	     570
	 3 Patrick	     590
	 4 Richard	     400

[email protected]>select * from emp2_part3;

     EMPNO ENAME	     SAL
---------- ---------- ----------
	 5 Hello	     350

alter table emp2 exchange partition emp2_p3 with table emp2_part3;

-- 會出錯

[email protected]>alter table emp2 exchange partition emp2_p3 with table emp2_part3;
alter table emp2 exchange partition emp2_p3 with table emp2_part3
                                                       *
ERROR at line 1:
ORA-14099: all rows in table do not qualify for specified partition


[email protected]>!oerr ora 14099
14099, 00000, "all rows in table do not qualify for specified partition"
// *Cause:  There is at least one row in the non partitioned table which
//          does not qualify for the partition specified in the ALTER TABLE
//          EXCHANGE PARTITION
// *Action: Ensure that all the rows in the segment qualify for the partition.
//          Perform the alter table operation with the NO CHECKING option.
//          Run ANALYZE table VALIDATE on that partition to find out the
//          invalid rows and delete them.

[email protected]>

END