oracle分割槽表線上重定義欄位not null問題
oracle透過DBMS_REDEFINITION進行線上重定義表,是基於物化檢視的方式將資料同步到新結構的中間表中,然後透過改名實現。
其中DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS儲存過程實現將相關依賴資訊也複製到中間表,但如果源表中有not null這種約束,就要注意。
以下測試:
環境:
os:centos 6.6
db:11.2.0.4
--建測試表源表
create table scott.tb_source as select * from dba_objects;
--修改源表兩個欄位為not null,以在後續步驟中產生錯誤
alter table scott.tb_source modify owner not null;
alter table scott.tb_source modify object_name not null;
--更新源表日期欄位,打散資料分佈
update scott.tb_source
set created=to_date('20150101','yyyymmdd')+dbms_random.value(1,1000);
commit;
--建測試表中間表,表結構為最終源表想轉換的表結構
--此處測試用的是有子分割槽的分割槽表,無子分割槽的分割槽表也可以
create table scott.tb_mid
(
owner VARCHAR2(30) not null,
object_name VARCHAR2(128) not null,
subobject_name VARCHAR2(30),
object_id NUMBER,
data_object_id NUMBER,
object_type VARCHAR2(19),
created DATE,
last_ddl_time DATE,
timestamp VARCHAR2(19),
status VARCHAR2(7),
temporary VARCHAR2(1),
generated VARCHAR2(1),
secondary VARCHAR2(1),
namespace NUMBER,
edition_name VARCHAR2(30)
)
partition by range (created)
subpartition by list (owner)
(
PARTITION p_2015 VALUES LESS THAN (to_date('20160101','yyyymmdd'))
(subpartition p_2015_sys values('SYS'),
subpartition p_2015_system values('SYSTEM'),
subpartition p_2015_other values(default)
),
PARTITION p_2016 VALUES LESS THAN (to_date('20170101','yyyymmdd'))
(subpartition p_2016_sys values('SYS'),
subpartition p_2016_system values('SYSTEM'),
subpartition p_2016_other values(default)
),
PARTITION p_max VALUES LESS THAN (maxvalue)
(subpartition p_max_sys values('SYS'),
subpartition p_max_system values('SYSTEM'),
subpartition p_max_other values(default)
)
);
--線上重定義
--1.檢查是否可以對源表進行重定義
--此處的options_flag根據源表上有主鍵選DBMS_REDEFINITION.cons_use_pk或1,無主鍵DBMS_REDEFINITION.cons_use_rowid或2
BEGIN
DBMS_REDEFINITION.CAN_REDEF_TABLE ('scott', 'tb_source', options_flag=>DBMS_REDEFINITION.cons_use_rowid);
END;
--2.開並行(可選)
alter session force parallel dml parallel 4;
alter session force parallel query parallel 4;
--3.開始線上重組
--此處的options_flag根據源表上有主鍵選DBMS_REDEFINITION.cons_use_pk或1,無主鍵DBMS_REDEFINITION.cons_use_rowid或2
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE('scott','tb_source','tb_mid',options_flag=>DBMS_REDEFINITION.cons_use_rowid);
END;
--4.複製表上的相關依賴資訊,如index,trigger,constraint,privilege,statistics
--該儲存過程引數如下:
/*PROCEDURE copy_table_dependents(uname IN VARCHAR2,
orig_table IN VARCHAR2,
int_table IN VARCHAR2,
copy_indexes IN PLS_INTEGER := 1,
copy_triggers IN BOOLEAN := TRUE,
copy_constraints IN BOOLEAN := TRUE,
copy_privileges IN BOOLEAN := TRUE,
ignore_errors IN BOOLEAN := FALSE,
num_errors OUT PLS_INTEGER,
copy_statistics IN BOOLEAN := FALSE,
copy_mvlog IN BOOLEAN := FALSE);*/
--下面在呼叫該儲存過程時ignore_errors=>true,忽略複製依賴資訊時的錯誤
DECLARE
num_errors PLS_INTEGER;
BEGIN
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS ('scott','tb_source','tb_mid',
DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);
END;
--5.檢視報錯資訊
--由於有not null約束,所以報以下錯誤。
--此問題的解決方法:1.忽略,只要只是報關天not null約束錯誤,因為其實中間表上的欄位已經not null
-- 2.在建中間表的時候把not null就去掉,這樣就會不出現此錯誤
select object_name, base_table_name, to_char(ddl_txt) from DBA_REDEFINITION_ERRORS;
/*
OBJECT_NAME BASE_TABLE_NAME TO_CHAR(DDL_TXT)
SYS_C0011143 TB_SOURCE ALTER TABLE "SCOTT"."TB_MID" MODIFY ("OBJECT_NAME" CONSTRAINT "TMP$$_SYS_C00111430" NOT NULL ENABLE NOVALIDATE)
SYS_C0011142 TB_SOURCE ALTER TABLE "SCOTT"."TB_MID" MODIFY ("OWNER" CONSTRAINT "TMP$$_SYS_C00111420" NOT NULL ENABLE NOVALIDATE)
*/
--6.同步源表到中間表,此過程可根據源表資料變化情況同步多次或0次
BEGIN
DBMS_REDEFINITION.SYNC_INTERIM_TABLE ('scott','tb_source','tb_mid');
END;
--7.完成線上重組
BEGIN
DBMS_REDEFINITION.FINISH_REDEF_TABLE ('scott','tb_source','tb_mid');
END;
--8.刪除中間表
drop table scott.tb_mid purge;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28539951/viewspace-2120248/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle 線上重新定義,普通表改變分割槽表,分割槽表可以更改型別、分割槽欄位等Oracle型別
- 線上重定義與普通表改為分割槽表
- 線上重定義方式將普通表修改為分割槽表
- 指令碼:線上重定義,從普通表到分割槽表,redefinition_table.sh指令碼
- PG的非分割槽表線上轉分割槽表
- 在oracle 9i下線上重定義表Oracle
- oracle分割槽表和分割槽表exchangeOracle
- 線上重定義的操作步驟__普通錶轉換為分割槽表的實驗案例
- Oracle 12C新特性-線上把非分割槽錶轉為分割槽表Oracle
- oracle分割槽表和非分割槽表exchangeOracle
- [oracle] expdp 匯出分割槽表的分割槽Oracle
- oracle 分割槽表move和包含分割槽表的lob moveOracle
- MySQL線上轉分割槽表(以及TiDB)MySqlTiDB
- ORACLE分割槽表梳理系列Oracle
- LightDB 22.4 新特性之相容Oracle線上轉換普通表為分割槽表Oracle
- Oracle分割槽表基礎運維-04列表分割槽Oracle運維
- Oracle分割槽表基礎運維-07增加分割槽(3列表分割槽)Oracle運維
- oracle將表配置為分割槽表Oracle
- oracle 普通表-分割槽表改造流程Oracle
- Oracle分割槽表基礎運維-07增加分割槽(2 HASH分割槽)Oracle運維
- Oracle分割槽表基礎運維-06分割槽表索引Oracle運維索引
- Oracle分割槽表基礎運維-09刪除分割槽Oracle運維
- Oracle分割槽表基礎運維-05組合分割槽Oracle運維
- Oracle分割槽表基礎運維-02範圍分割槽Oracle運維
- Oracle分割槽表基礎運維-03HASH分割槽Oracle運維
- Oracle分割槽表基礎運維-07增加分割槽(1範圍分割槽)Oracle運維
- 分割槽使用與Oracle許可證問題XSOracle
- Oracle分割槽表基礎運維-01分割槽表分類Oracle運維
- PostgreSQL/LightDB分割槽表之常見問題SQL
- 對oracle分割槽表的理解整理Oracle
- Oracle SQL調優之分割槽表OracleSQL
- Oracle 12.2之後ALTER TABLE .. MODIFY轉換非分割槽表為分割槽表Oracle
- 關於建表欄位是否該使用not null這個問題你怎麼看?Null
- interval 分割槽表clob預設表空間指定問題
- 壓縮錶轉非壓縮表(線上重定義)
- 對Oracle分割槽表進行表空間遷移並處理ORA-14511問題Oracle
- ORACLE刪除-表分割槽和資料Oracle
- Oracle有沒有MySQL的分割槽DDL遇到的問題OracleMySql
- mysql 5.7.11查詢分割槽表的一個問題MySql