使用 Data Pump (expdp/impdp) 進行跨字符集、跨表空間遷移時,常遇到 ORA-12899: value too large for column (字符集轉換導致長度超限) 與 ORA-02291: integrity constraint violated - parent key not found (主外鍵順序問題)。本文記錄實戰解決方案。
DATA_ONLY (僅數據)impdp test/test directory=exp_dump dumpfile=test.dmp remap_schema=test1:test2 remap_tablespace=TBS_DAT_1:TBS_DAT_2,TBS_IDX_1:TBS_IDX_2KUP-11007: conversion error loading table "TEST"."T_PSR"
ORA-12899: value too large for column "REASON_CODE" (actual: 21, maximum: 20)
KUP-11009: data for row: REASON_CODE : 0X'BABDBFD5C6F7C8DDC1BFCFDED6C6'
REASON_CODE VARCHAR2(20 BYTE) 存儲 10 個漢字 (20 bytes GBK)。ALTER TABLE test2.T_PSR MODIFY REASON_CODE VARCHAR2(60 BYTE); -- 20*3 預留餘量
CREATE TABLE ... (REASON_CODE VARCHAR2(20 CHAR) ...); -- 按字符數而非位元組
expdp ... content=METADATA_ONLY),修改 DDL 中字段長度後先建表,再 impdp ... content=DATA_ONLY。ORA-31693: Table data object "TEST"."T_ITE" failed to load
ORA-02291: integrity constraint (TEST.FK_ITE_REF_PSR) violated - parent key not found
expdp ... content=DATA_ONLY 僅導出數據,**不導出約束定義**。T_ITE 數據先於父表 T_PSR 導入,外鍵檢查失敗。-- 1. 導入前:生成禁用外鍵腳本
SELECT 'ALTER TABLE ' || TABLE_NAME || ' DISABLE CONSTRAINT ' || CONSTRAINT_NAME || ';'
FROM USER_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'R';
-- 執行輸出的 SQL
-- 2. 執行 impdp 導入數據
-- 3. 導入後:生成啟用約束腳本 (NOVALIDATE 不驗證既有數據)
SELECT 'ALTER TABLE ' || TABLE_NAME || ' ENABLE NOVALIDATE CONSTRAINT ' || CONSTRAINT_NAME || ';'
FROM USER_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'R';
-- 執行輸出的 SQL
-- 4. 可選:後續手動驗證或 ENABLE VALIDATE
-- ALTER TABLE ... ENABLE VALIDATE CONSTRAINT ...; -- 會全表掃描驗證
關鍵點: NOVALIDATE 讓約束對**未來**數據生效,不阻塞導入;歷史數據一致性由來源庫保證。
VARCHAR2(BYTE) 字段擴容需求,優先採用 CHAR 語義。DATA_ONLY 導入必須配合約束禁用/啟用腳本自動化。remap_tablespace 參數正確配置,避免空間不足。PARALLEL=4 (視 CPU 核心) 顯著提升導入速度。