ORA-14400: inserted partition key does not map to any partition は、Oracleのパーティション表へINSERTしようとした値が、どのパーティションにも割り当てられないときに発生するエラーです。日付の月次パーティション追加漏れ、VALUES LESS THAN の境界値ミス、LISTパーティションの値不足、バッチ投入対象月のズレなどでよく起きます。
Oracle公式のエラー説明では、RangeまたはComposite Rangeでは挿入値が最後のパーティション境界を超えた場合、Listでは指定値に合うパーティションがない場合に発生するとされています。対処は、挿入値を修正するか、値を受け入れられるパーティションを追加することです。パーティション表全体の基礎は Oracleパーティションテーブル完全ガイド、運用自動化は PL/SQLパーティションテーブル運用を自動化する方法 もあわせて確認してください。
- ORA-14400が起きる条件
- RANGE、LIST、INTERVALパーティションでの原因の違い
- パーティションキー列と既存パーティション境界の確認SQL
- 月次パーティションの追加漏れを直すSQL
- MAXVALUE、INTERVAL、DEFAULTパーティションの使い分け
- SQL*Loader、APPEND、バッチ投入での注意点
- 再発防止のチェックリスト
- 重複確認結果
- 最初に結論:値に合うパーティションを追加する
- 原因別の判断フロー
- ORA-14400が起きる典型パターン
- まずパーティションキー列を確認する
- 既存パーティション境界を確認する
- 対象値がどのパーティションに入るか確認する
- 解決1:RANGEパーティションを追加する
- 解決2:MAXVALUEパーティションを用意する
- 解決3:INTERVALパーティションを使う
- 解決4:LISTパーティションに値またはDEFAULTを追加する
- SQL*LoaderやAPPEND投入での注意点
- パーティション追加後に統計情報を確認する
- ローカルインデックス・グローバルインデックスの注意点
- 再発防止:月次パーティションを事前作成する
- 避けたい対応
- 本番投入前チェックリスト
- まとめ
重複確認結果
本番DBで ORA-14400、英語メッセージ、パーティションキー、パーティション追加漏れを検索しましたが、ORA-14400単独記事は見つかりませんでした。既存にはパーティション表、パーティション運用、パーティションインデックスの記事があるため、この記事はエラー対処の入口として作成しています。
最初に結論:値に合うパーティションを追加する
ORA-14400の直接原因は、挿入しようとしたパーティションキー値に対応するパーティションが存在しないことです。まず、どの列がパーティションキーか、挿入しようとした値はいくつか、既存パーティションの境界はどこまでかを確認します。
ALTER TABLE ... ADD PARTITION で対象月を受け入れるパーティションを追加します。VALUES LESS THAN は上限値を含みません。月初や時刻付きDATEで失敗しやすいです。大量投入や高速ロードで同時に問題が出る場合は ダイレクト・パス・インサート完全ガイド、SQL*Loader経由なら SQL*Loader完全ガイド も関連します。
原因別の判断フロー
ORA-14400は、パーティションの種類と投入値を見ると原因を切り分けやすいです。まず対象表のパーティション方式を確認し、そのうえで投入値が境界外なのか、未定義コードなのか、将来日付なのかを見ます。
VALUES LESS THAN は上限を含みません。月初日付や時刻付きDATEを確認します。ORA-14400が起きる典型パターン
一番多いのは、月次や日次のRANGEパーティションで、投入対象日のパーティションを事前に作っていないケースです。特に月初、年初、将来日付、データ移行、遅延到着データで発生しやすくなります。
月次パーティション追加漏れ
CREATE TABLE sales ( sales_id NUMBER, sales_date DATE NOT NULL, amount NUMBER ) PARTITION BY RANGE (sales_date) ( PARTITION p202604 VALUES LESS THAN (DATE '2026-05-01'), PARTITION p202605 VALUES LESS THAN (DATE '2026-06-01') ); -- 2026年6月分を受けるパーティションがないため ORA-14400 INSERT INTO sales (sales_id, sales_date, amount) VALUES (1, DATE '2026-06-01', 1000);
LISTパーティションの値不足
CREATE TABLE customers_by_region (
customer_id NUMBER,
region_code VARCHAR2(10)
)
PARTITION BY LIST (region_code) (
PARTITION p_jp VALUES ('JP'),
PARTITION p_us VALUES ('US')
);
-- EUを受けるパーティションがないため ORA-14400
INSERT INTO customers_by_region (customer_id, region_code)
VALUES (100, 'EU');
境界値の勘違い
VALUES LESS THAN (DATE '2026-06-01') は、2026年6月1日を含みません。2026年5月31日23:59:59までは入り得ますが、2026年6月1日00:00:00は次のパーティションが必要です。
-- p202605 は 2026-06-01 未満だけを受ける PARTITION p202605 VALUES LESS THAN (DATE '2026-06-01') -- これは入らない。次の p202606 が必要 DATE '2026-06-01'
まずパーティションキー列を確認する
エラー対象の表で、どの列がパーティションキーになっているかを確認します。複合パーティションキーの場合、複数列の組み合わせで判断されます。
SELECT name,
object_type,
column_name,
column_position
FROM user_part_key_columns
WHERE name = 'SALES'
ORDER BY column_position;
SELECT table_name,
partitioning_type,
subpartitioning_type,
partition_count
FROM user_part_tables
WHERE table_name = 'SALES';
アプリ側のINSERT文だけ見ていると、パーティションキー列にどんな値が入っているか見落とすことがあります。バインド変数や変換処理後の実値を確認することが重要です。
既存パーティション境界を確認する
次に、既存パーティションがどの範囲を受けているか確認します。HIGH_VALUE はLONG型なので扱いにくいですが、まずはSQL*PlusやSQL Developerで確認する用途なら次のSQLで十分です。
SELECT partition_name,
partition_position,
high_value,
tablespace_name,
num_rows,
last_analyzed
FROM user_tab_partitions
WHERE table_name = 'SALES'
ORDER BY partition_position;
DDLとして確認したい場合は DBMS_METADATA.GET_DDL を使うと、パーティション定義全体を確認できます。
SELECT DBMS_METADATA.GET_DDL('TABLE', 'SALES')
FROM dual;
DDL取得の詳細は DBMS_METADATA完全解説 も参考になります。
対象値がどのパーティションに入るか確認する
Oracleでは PARTITION FOR を使って、指定したキー値に対応するパーティションを参照できます。対応パーティションがなければ、同じ原因で失敗します。
-- 指定日が入るパーティションを確認する SELECT COUNT(*) FROM sales PARTITION FOR (DATE '2026-06-15'); -- 対応パーティションがなければエラーになるため、投入前チェックに使える
本番バッチでは、投入対象期間の最小日付・最大日付を先に集計し、その範囲を受けるパーティションがあるか確認します。
SELECT MIN(sales_date) AS min_sales_date,
MAX(sales_date) AS max_sales_date,
COUNT(*) AS row_count
FROM sales_load_work
WHERE batch_id = :batch_id;
範囲外の投入値を特定する
月次パーティション運用では、投入データの最大日付が既存パーティションの最大境界を超えていないかを確認します。HIGH_VALUE はそのまま比較しにくいため、運用上はパーティション境界を管理テーブルで持つ方法も有効です。
CREATE TABLE partition_boundary_master (
table_name VARCHAR2(128) NOT NULL,
partition_name VARCHAR2(128) NOT NULL,
lower_date DATE,
upper_date DATE NOT NULL,
CONSTRAINT pk_partition_boundary_master
PRIMARY KEY (table_name, partition_name)
);
-- 投入データがどの管理境界にも入らない値を確認する
SELECT w.sales_date,
COUNT(*) AS row_count
FROM sales_load_work w
WHERE w.batch_id = :batch_id
AND NOT EXISTS (
SELECT 1
FROM partition_boundary_master b
WHERE b.table_name = 'SALES'
AND w.sales_date >= NVL(b.lower_date, DATE '0001-01-01')
AND w.sales_date < b.upper_date
)
GROUP BY w.sales_date
ORDER BY w.sales_date;
LISTの未定義コードを特定する
CREATE TABLE region_partition_master (
region_code VARCHAR2(10) PRIMARY KEY
);
INSERT INTO region_partition_master(region_code) VALUES ('JP');
INSERT INTO region_partition_master(region_code) VALUES ('US');
SELECT w.region_code,
COUNT(*) AS row_count
FROM customers_load_work w
WHERE NOT EXISTS (
SELECT 1
FROM region_partition_master m
WHERE m.region_code = w.region_code
)
GROUP BY w.region_code
ORDER BY w.region_code;
解決1:RANGEパーティションを追加する
月次パーティションが足りない場合は、次の月を受けるパーティションを追加します。VALUES LESS THAN には、そのパーティションの上限値を指定します。
ALTER TABLE sales ADD PARTITION p202606 VALUES LESS THAN (DATE '2026-07-01') TABLESPACE sales_ts;
2026年6月分を受けるパーティションなら、上限は2026年7月1日です。パーティション名は pYYYYMM のように運用しやすい規則にすると、自動追加や監視が簡単になります。
解決2:MAXVALUEパーティションを用意する
想定外の将来日付を一時的に受けたい場合、RANGEパーティションの末尾に MAXVALUE パーティションを置く設計があります。ただし、何でも受けてしまうため、後から適切な月次パーティションへ分割・移動する運用が必要です。
CREATE TABLE sales (
sales_id NUMBER,
sales_date DATE NOT NULL,
amount NUMBER
)
PARTITION BY RANGE (sales_date) (
PARTITION p202605 VALUES LESS THAN (DATE '2026-06-01'),
PARTITION pmax VALUES LESS THAN (MAXVALUE)
);
-- pmaxを月次パーティションへ分割する例
ALTER TABLE sales
SPLIT PARTITION pmax AT (DATE '2026-07-01')
INTO (
PARTITION p202606,
PARTITION pmax
);
MAXVALUEは安全弁になりますが、放置するとpmaxにデータが溜まり、パーティション設計の意味が薄れます。定期的な分割と統計情報収集をセットにします。
解決3:INTERVALパーティションを使う
毎月パーティションを手動追加する運用を避けたい場合、RANGEパーティションをINTERVALパーティションとして設計する方法があります。指定した間隔で、新しい値に応じたパーティションが自動作成されます。
CREATE TABLE sales ( sales_id NUMBER, sales_date DATE NOT NULL, amount NUMBER ) PARTITION BY RANGE (sales_date) INTERVAL (NUMTOYMINTERVAL(1, 'MONTH')) ( PARTITION p202601 VALUES LESS THAN (DATE '2026-02-01') ); -- 2026年6月のデータをINSERTすると、必要なINTERVALパーティションが作成される INSERT INTO sales (sales_id, sales_date, amount) VALUES (1, DATE '2026-06-15', 1000);
INTERVALパーティションは便利ですが、命名規則、表領域、古いデータの削除、ローカルインデックス、統計情報収集をどう運用するか決めておく必要があります。パーティションインデックスは Oracleパーティションインデックス完全ガイド が関連します。
INTERVALパーティションの注意点
解決4:LISTパーティションに値またはDEFAULTを追加する
LISTパーティションでは、挿入値がどの VALUES にも一致しないとORA-14400になります。新しいコードを正式に扱うなら個別パーティションを追加し、想定外値を一時的に受けるならDEFAULTパーティションを検討します。
ALTER TABLE customers_by_region
ADD PARTITION p_eu VALUES ('EU');
-- 想定外値を受ける安全弁
ALTER TABLE customers_by_region
ADD PARTITION p_other VALUES (DEFAULT);
DEFAULTパーティションは便利ですが、データ品質の問題を隠すことがあります。不明コードを受けたら監視やレポートで検知し、正式なパーティションへ移す運用を作ります。
SQL*LoaderやAPPEND投入での注意点
大量データロードでは、ORA-14400が出るとロード途中で失敗行が発生します。ロード前にデータの最小・最大日付、コード値の一覧を確認し、必要なパーティションを作ってから投入します。
-- ロード前に対象日付範囲を確認する
SELECT MIN(sales_date) AS min_date,
MAX(sales_date) AS max_date,
COUNT(*) AS rows_to_load
FROM sales_load_work;
-- LISTパーティションなら未知コードを確認する
SELECT region_code,
COUNT(*) AS row_count
FROM customers_load_work
GROUP BY region_code
ORDER BY region_code;
APPENDや並列DMLを使う場合は、パーティション不足に加えてORA-12838にも注意します。詳しくは ORA-12838の原因と解決方法 を確認してください。
パーティション追加後に統計情報を確認する
パーティションを追加・分割した後は、統計情報の状態も確認します。特に大量ロード後やパーティション分割後は、対象パーティションまたは表全体の統計情報を収集します。
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(
ownname => USER,
tabname => 'SALES',
partname => 'P202606',
granularity => 'PARTITION',
cascade => TRUE
);
END;
/
統計情報の詳しい管理は DBMS_STATSによる統計情報の手動収集・管理完全ガイド、列の組み合わせによる見積もり改善は 拡張統計完全ガイド が関連します。
ローカルインデックス・グローバルインデックスの注意点
パーティション追加だけなら影響は軽いことが多いですが、SPLIT、DROP、TRUNCATE、EXCHANGEを行う場合はインデックス状態に注意します。グローバルインデックスがUNUSABLEになる運用では、後続SQLやバッチが失敗することがあります。
USER_INDEXES や USER_IND_PARTITIONS を確認します。インデックスがUNUSABLEになった場合は ORA-01502の原因と解決方法 が関連します。
再発防止:月次パーティションを事前作成する
月次パーティション運用では、翌月・翌々月のパーティションを事前に作るジョブを用意しておくと安全です。バッチ当日に追加する運用は、失敗時の影響が大きくなります。
-- 次月を受けるパーティションが存在するか確認する例
SELECT partition_name,
high_value
FROM user_tab_partitions
WHERE table_name = 'SALES'
ORDER BY partition_position DESC
FETCH FIRST 3 ROWS ONLY;
実務では、パーティション追加ジョブ、失敗通知、追加後の統計情報収集、ローカルインデックス確認までをセットにします。
避けたい対応
本番投入前チェックリスト
- エラー対象表のパーティションキー列を確認した
- 投入データの最小値・最大値・コード一覧を確認した
- 既存パーティションの
HIGH_VALUEを確認した VALUES LESS THANが上限値を含まないことを理解している- 必要な月次・日次パーティションを事前に追加した
- LISTパーティションでは未知コードをどう扱うか決めた
- MAXVALUEやDEFAULTを使う場合、後続の分割・棚卸し運用を決めた
- INTERVALパーティションを使う場合、表領域・命名・統計情報収集を確認した
- パーティション追加後にローカル/グローバルインデックス状態を確認した
- 大量ロード後にパーティション統計を収集する手順を用意した
まとめ
ORA-14400は、INSERTしようとしたパーティションキー値に対応するパーティションが存在しない時に発生します。RANGEなら境界値と月次追加漏れ、LISTなら値の定義漏れ、INTERVALなら自動作成の適用条件を確認します。
対処は、挿入値を修正するか、値を受け入れるパーティションを追加することです。本番では、事前チェック、翌月パーティションの自動追加、統計情報収集、インデックス状態確認まで含めて運用化すると、月初やバッチ投入時の事故を減らせます。

