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