DBインポートでキー重複

通常、インポートの際に プライマリキー( PK )項目が既存データと重複する場合、
制約違反でエラーになってしまう。これを回避するためには、2つの方法がある。

  • QUERY オプション
  • DATA_OPTIONS オプション
  • QUERY オプション

    ダンプファイル内の対象データの範囲を指定できるため、
    重複していないデータだけを指定してインポート可能。

    例えば PK 項目の ID 列が 1~9 まで既に存在する場合に、
    QUERY=\”WHERE ID \>= 10\” とすることで、ID が 10 以上の
    データしかインポートされなくなり、重複エラーを回避できる。

    SQLサンプル

    impdp oracle/oracle \
     DIRECTORY=DMPDIR \
     TABLES=TEST \
     TABLE_EXISTS_ACTION=append \
     QUERY=\"WHERE ID \>= 10\" \
     CONTENT=data_only \
     DUMPFILE=TEST.dmp \
     LOGFILE=TEST_IMP.log
    

    Windows、Unix などプラットフォームによって異なるが、引用符や記号( “” 、> など)は
    前に \ を指定してエスケープしないと正しく認識されない。
    (誤りがある場合は、 ORA-39001 や ORA-39035 が発生する)

    なお、各オプションの行末にある \ は別物で、改行を認識させるための指定。

    DATA_OPTIONS オプション

    SKIP_CONSTRAINT_ERRORS を指定することで、制約に引っかかった場合に
    その行をスキップして、正常データのみインポート可能。

    SQLサンプル

    impdp oracle/oracle \
     DIRECTORY=DMPDIR \
     TABLES=TEST \
     TABLE_EXISTS_ACTION=append \
     CONTENT=data_only \
     DATA_OPTIONS=skip_constraint_errors \
     DUMPFILE=TEST.dmp \
     LOGFILE=TEST_IMP.log
    

    ID が 1~9 の重複データは、制約エラーとして表示される。

    ORA-00001: 一意制約(ORACLE.TEST)に反しています

    主キーのある拒否された行:
    拒否された行番号1:
    列ID: 1
    ~ 中略 ~
    拒否された行番号9:
    列ID: 9

    重複していないデータはスキップされることなく、インポートされる。

    【まとめ】

    「(1) QUERY オプション」は対象が明確な場合に有効だが、データが大量で
    重複範囲もバラバラであったり、そもそも対象が把握できていない場合には非効率。
    「(2) DATA_OPTIONS オプション」の方が実用的。

    関連記事