首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

impdp 導入實戰避坑:字符集轉換截斷與主外鍵約束違規解決

     編輯:DB2 教學

impdp 導入實戰避坑:字符集轉換截斷與主外鍵約束違規解決

使用 Data Pump (expdp/impdp) 進行跨字符集、跨表空間遷移時,常遇到 ORA-12899: value too large for column (字符集轉換導致長度超限) 與 ORA-02291: integrity constraint violated - parent key not found (主外鍵順序問題)。本文記錄實戰解決方案。

場景背景

  • 來源庫:11.2.0.4,字符集 **ZHS16GBK**,導出模式 DATA_ONLY (僅數據)
  • 目標庫:11.2.0.4,字符集 **AL32UTF8**
  • 數據量:10+ 表,<1000萬行,Dump ~400MB
  • 導入命令: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_2

問題一:字符集轉換導致字段長度超限 (ORA-12899)

錯誤現象

KUP-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'

根因分析

  • GBK 中漢字佔 **2 bytes**,UTF8 中佔 **3 bytes**。
  • 源表 REASON_CODE VARCHAR2(20 BYTE) 存儲 10 個漢字 (20 bytes GBK)。
  • 導入 UTF8 目標庫時,同樣 10 個漢字變為 30 bytes,**超過 20 bytes 定義**。

解決方案

  1. 預先擴充目標表字段 (推薦):
    ALTER TABLE test2.T_PSR MODIFY REASON_CODE VARCHAR2(60 BYTE);  -- 20*3 預留餘量
  2. 使用 CHAR 語義定義 (長期方案):
    CREATE TABLE ... (REASON_CODE VARCHAR2(20 CHAR) ...);  -- 按字符數而非位元組
  3. 導入前預處理: 導出 DDL (expdp ... content=METADATA_ONLY),修改 DDL 中字段長度後先建表,再 impdp ... content=DATA_ONLY。

問題二:主外鍵約束違規 (ORA-02291)

錯誤現象

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 導入,外鍵檢查失敗。

解決方案:禁用約束 → 導入 → 啟用約束 (NOVALIDATE)

-- 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 讓約束對**未來**數據生效,不阻塞導入;歷史數據一致性由來源庫保證。

總結最佳實踐清單

  1. 字符集遷移: 必須評估 VARCHAR2(BYTE) 字段擴容需求,優先採用 CHAR 語義。
  2. 約束管理: DATA_ONLY 導入必須配合約束禁用/啟用腳本自動化。
  3. 表空間重映射: remap_tablespace 參數正確配置,避免空間不足。
  4. 並行度: PARALLEL=4 (視 CPU 核心) 顯著提升導入速度。
  5. 驗證機制: 導入後抽樣核對行數、關鍵欄位 checksum、約束狀態。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved