Data Pump Import(impdp)で既存のテーブルがある環境にインポートする場合、既存データを上書きしたくないケースがあります。table_exists_action=SKIP を指定すれば、既に存在するテーブルはスキップし、存在しないテーブルだけをインポートできます。
本記事では、SKIP の動作と注意点、ORA-31684 エラーとの関係、スキップされたテーブルの確認方法、不足テーブルだけ追加するパターン、そして 4 つの table_exists_action の使い分けまで解説します。
・table_exists_action=SKIP の動作
・SKIP がデフォルトである理由と ORA-31684 の関係
・スキップされたテーブルをログで確認する方法
・SKIP で「不足テーブルだけ追加」するパターン
・SKIP / REPLACE / APPEND / TRUNCATE の使い分け判断フロー
・content=DATA_ONLY / METADATA_ONLY との組み合わせ
table_exists_action=SKIP の動作
# 既存テーブルをスキップしてインポート(デフォルト動作)
impdp hr/password \
directory=DP_DIR \
dumpfile=hr_export.dmp \
logfile=hr_import.log \
schemas=HR \
table_exists_action=SKIP
# table_exists_action を省略しても SKIP がデフォルト
impdp hr/password \
directory=DP_DIR \
dumpfile=hr_export.dmp \
schemas=HR
| テーブル | 移行先に存在 | SKIP の動作 |
|---|---|---|
| EMPLOYEES | あり | スキップ(何もしない) |
| DEPARTMENTS | あり | スキップ(何もしない) |
| NEW_TABLE | なし | 作成 + データ投入 |
既存テーブルは一切変更せず、ダンプに含まれていて移行先に存在しないテーブルだけが作成されます。既存データを保護する最も安全なオプションです。
ORA-31684 と SKIP の関係
ORA-31684: Object type TABLE:"HR"."EMPLOYEES" already exists ORA-31684: Object type TABLE:"HR"."DEPARTMENTS" already exists Table "HR"."NEW_TABLE" successfully imported
ORA-31684 は「オブジェクトが既に存在する」という情報メッセージであり、エラーではありません。table_exists_action=SKIP の場合、このメッセージは「スキップしました」という正常な動作報告です。
impdp のログに ORA-31684 が出ても慌てる必要はありません。SKIP を指定(またはデフォルト)していれば、「既存テーブルはスキップし、存在しないテーブルだけインポートした」という意味です。ログの最後の「successfully completed」を確認してください。
スキップされたテーブルを確認する方法
# ORA-31684 の行を grep でスキップされたテーブルを確認 grep 'ORA-31684' /oracle/dpdir/hr_import.log # 正常にインポートされたテーブルを確認 grep 'successfully imported' /oracle/dpdir/hr_import.log # スキップ数と成功数のカウント echo "Skipped: $(grep -c 'ORA-31684' /oracle/dpdir/hr_import.log)" echo "Imported: $(grep -c 'successfully imported' /oracle/dpdir/hr_import.log)"
-- ダンプに含まれるテーブル一覧を確認(sqlfile で DDL だけ出力) -- impdp hr/password directory=DP_DIR dumpfile=hr_export.dmp sqlfile=check.sql -- 移行先のテーブル一覧 SELECT table_name FROM user_tables ORDER BY table_name;
SKIP が最適なケース
| ケース | 説明 |
|---|---|
| 不足テーブルの補完 | スキーマの一部テーブルだけが欠けている環境にダンプから補完 |
| 既存データの保護 | 本番環境にインポートする際、既存テーブルを絶対に上書きしたくない |
| 冪等なインポート | 同じダンプを複数回実行しても結果が変わらない(2 回目以降は全スキップ) |
| マイグレーションの段階的実行 | 先にテーブルだけ作成、後からデータだけ追加(content 使い分け) |
table_exists_action の 4 つのオプション比較
| オプション | 既存テーブル | 既存データ | ロールバック | 用途 |
|---|---|---|---|---|
| SKIP(デフォルト) | スキップ(何もしない) | 維持される | 不要 | 既存データを保護。不足テーブルの追加 |
| REPLACE | DROP して再作成 | 全削除 | 不可(DDL) | テーブルを完全に置き換え |
| APPEND | 維持(データを追加) | 維持 + 追加 | COMMIT 前可 | 差分データの追加。主キー重複に注意 |
| TRUNCATE | 維持(TRUNCATE + 投入) | 全削除 → 投入 | 不可(DDL) | テーブル構造は維持してデータ入れ替え |
判断フロー
・既存テーブルに触れたくない → SKIP
・既存テーブルを完全に置き換えたい(構造含む)→ REPLACE
・既存テーブルにデータを追加したい → APPEND
・テーブル構造は維持してデータだけ入れ替えたい → TRUNCATE
table_exists_action の全オプションの詳細は「ORA-31684 完全解説」を参照してください。
SKIP と content の組み合わせ
| 組み合わせ | 動作 | 用途 |
|---|---|---|
| SKIP + content=ALL(デフォルト) | 存在しないテーブルの構造 + データを作成 | 不足テーブルの完全補完 |
| SKIP + content=METADATA_ONLY | 存在しないテーブルの構造だけ作成(データなし) | 空テーブルの補完 |
| SKIP + content=DATA_ONLY | テーブルが存在しなければエラー(CREATE しないため) | 通常は使わない組み合わせ |
# 存在しないテーブルの DDL だけ実行(データは投入しない)
impdp hr/password \
directory=DP_DIR \
dumpfile=hr_export.dmp \
schemas=HR \
content=METADATA_ONLY \
table_exists_action=SKIP
# 既存テーブル → スキップ
# 不足テーブル → CREATE TABLE のみ実行(データなし)
content=DATA_ONLY は CREATE TABLE を実行しないため、テーブルが存在しない場合はデータの投入先がなくエラーになります。DATA_ONLY を使う場合は SKIP ではなく APPEND または TRUNCATE を使ってください。
EXCLUDE / INCLUDE との組み合わせ
# 特定テーブルを除外 + 残りは SKIP で不足分だけ追加
impdp hr/password \
directory=DP_DIR \
dumpfile=hr_export.dmp \
schemas=HR \
table_exists_action=SKIP \
exclude=TABLE:\"IN ('TEMP_LOG', 'AUDIT_OLD')\"
# skip_import.par
directory=DP_DIR
dumpfile=hr_export.dmp
logfile=skip_import.log
schemas=HR
table_exists_action=SKIP
exclude=TABLE:"IN ('TEMP_LOG', 'AUDIT_OLD')"
テーブル以外のオブジェクトの SKIP 動作
| オブジェクト | 既存時の動作 | 備考 |
|---|---|---|
| テーブル | SKIP(ORA-31684) | table_exists_action で制御 |
| インデックス | スキップ(ORA-31684) | テーブルがスキップされるとインデックスもスキップ |
| 制約 | スキップ(ORA-31684) | テーブルに紐づく制約もスキップ |
| ビュー | スキップ(ORA-31684) | 既存ビューは上書きされない |
| シーケンス | スキップ(ORA-31684) | 既存シーケンスの現在値は維持 |
| プロシージャ / パッケージ | 上書きされる(CREATE OR REPLACE) | 注意: PL/SQL は常に上書き |
| トリガー | 上書きされる(CREATE OR REPLACE) | 同上 |
PL/SQL オブジェクトは
CREATE OR REPLACE で作成されるため、table_exists_action=SKIP でも上書きされます。既存の PL/SQL を保護したい場合は EXCLUDE=PROCEDURE,FUNCTION,PACKAGE,TRIGGER で除外してください。実務パターン集
パターン(1): マイグレーションで不足テーブルだけ追加
# 本番スキーマに不足しているテーブルだけ追加
impdp system/password \
directory=DP_DIR \
dumpfile=dev_schema.dmp \
schemas=HR \
table_exists_action=SKIP \
logfile=add_missing_tables.log
# ログで追加されたテーブルを確認
grep 'successfully imported' /oracle/dpdir/add_missing_tables.log
パターン(2): 安全な環境構築(冪等インポート)
# CI/CD パイプラインで毎回実行しても安全
# 1 回目: 全テーブル作成
# 2 回目以降: 全テーブルスキップ(変更なし)
impdp hr/password \
directory=DP_DIR \
dumpfile=initial_schema.dmp \
schemas=HR \
table_exists_action=SKIP \
logfile=setup.log
パターン(3): テーブル構造だけ補完(データなし)
# 検証環境に不足テーブルの構造だけ追加(データは後から投入)
impdp hr/password \
directory=DP_DIR \
dumpfile=hr_schema.dmp \
schemas=HR \
content=METADATA_ONLY \
table_exists_action=SKIP \
exclude=PROCEDURE,FUNCTION,PACKAGE,TRIGGER
# PL/SQL は EXCLUDE で保護(上書き防止)
パターン(4): SKIP + 後から APPEND でデータ追加
# ステップ(1): 構造だけインポート(SKIP: 既存テーブルは変更なし)
impdp hr/password \
directory=DP_DIR \
dumpfile=hr_schema.dmp \
schemas=HR \
content=METADATA_ONLY \
table_exists_action=SKIP
# ステップ(2): データだけ追加(APPEND: 既存データを維持して追加)
impdp hr/password \
directory=DP_DIR \
dumpfile=hr_schema.dmp \
schemas=HR \
content=DATA_ONLY \
table_exists_action=APPEND
よくある質問
table_exists_action=SKIP と書いた方が意図が明確になり、保守性が向上します。EXCLUDE=PROCEDURE,FUNCTION,PACKAGE,TRIGGER を指定してください。DBMS_STATS.GATHER_SCHEMA_STATS(USER, OPTIONS => 'GATHER EMPTY') で統計が未収集のテーブルだけ収集することを推奨します。まとめ
table_exists_action=SKIP の要点をまとめます。
| やりたいこと | 設定 |
|---|---|
| 既存テーブルを保護して不足分だけ追加 | table_exists_action=SKIP(デフォルト) |
| 不足テーブルの構造だけ追加(データなし) | SKIP + content=METADATA_ONLY |
| ORA-31684 のスキップ対象を確認 | grep ‘ORA-31684’ import.log |
| PL/SQL の上書きを防止 | EXCLUDE=PROCEDURE,FUNCTION,PACKAGE,TRIGGER |
| 冪等なインポート(何度実行しても同じ結果) | SKIP で毎回実行(2 回目以降は全スキップ) |
| データの追加(SKIP とは異なる) | table_exists_action=APPEND |
| テーブルを完全に置き換え | table_exists_action=REPLACE |
table_exists_action の全 4 オプションの詳細は「ORA-31684 完全解説」、Data Pump の基本は「Data Pump の使い方完全ガイド」、データ保護のリストア手法は「テーブルリストア時に既存データを保護する方法」も併せて参照してください。

