ORA-01843: 指定した月が無効です。は、Oracleで日付を扱うSQLを実行した際に非常によく発生するエラーのひとつです。
特にINSERTやUPDATE、TO_DATE関数を使用した処理で突然発生し、「SQL自体は正しいはずなのに動かない」という状況になりやすい特徴があります。
実務でも、環境移行後やSQL改修後にこのエラーが発生するケースが多く、原因はほぼ共通しています。結論から言うと、Oracleが解釈しようとしている日付形式と、実際に渡している文字列の日付形式が一致していないことが原因です。
本記事では、ORA-01843が発生する仕組みと具体的な修正方法をについて解説します。
ORA-01843: 指定した月が無効です。とは
ORA-01843は、Oracleが文字列をDATE型へ変換する際に、月情報を正しく解釈できなかった場合に発生します。
代表的なエラーメッセージ:
ORA-01843: 指定した月が無効です。
これは「月の値が存在しない」という意味ではなく、日付フォーマットの不一致を示しています。
ORA-01843が発生する主な原因
発生原因はほぼ以下に集約されます。
| 原因 | 内容 |
|---|---|
| 日付フォーマット不一致 | TO_DATEの書式と文字列が一致していない |
| NLS_DATE_FORMAT依存 | セッションの日付設定に依存している |
| DATE型へ文字列直接代入 | Oracle内部変換が失敗 |
| 月表記の誤り | MMとMONの混在 |
| 既にDATE型なのに再変換 | 不要なTO_DATE使用 |
原因① TO_DATEのフォーマット不一致
最も多い原因です。
誤った例
|
1 |
TO_DATE('2024-12-01','YYYY/MM/DD') |
文字列は「-」区切りですが、フォーマットは「/」区切りです。
Oracleは完全一致で解析するためエラーになります。

日付フォーマットの不一致が原因で発生するOracleエラーには、ORA-01843以外にも代表的なものがあります。
書式と文字列が一致しない場合に発生する 「ORA-01861 : リテラルが書式文字列と一致しません」 の原因と対処法については、以下の記事で詳しく解説しています。

正しい例
|
1 |
TO_DATE('2024-12-01','YYYY-MM-DD') |
区切り文字まで一致させる必要があります。
原因② NLS_DATE_FORMATに依存している
DATE型カラムへ文字列を直接INSERTすると、Oracleは暗黙変換を行います。
危険なSQL
|
1 |
INSERT INTO TEST_TABLE VALUES ('2024/12/01'); |
この場合、Oracleはセッションの以下設定を使用します。
|
1 |
NLS_DATE_FORMAT |
環境によって値が異なるため、本番のみエラーになる原因になります。
確認方法
|
1 2 |
SELECT * FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT'; |
原因③ DATE型へ文字列を直接代入している
暗黙変換に依存するとORA-01843が発生しやすくなります。
NG例
|
1 2 |
UPDATE TEST_TABLE SET CREATE_DATE = '2024-12-01'; |
推奨方法
|
1 2 3 |
UPDATE TEST_TABLE SET CREATE_DATE = TO_DATE('2024-12-01','YYYY-MM-DD'); |
明示的に変換してください。
原因④ 月フォーマット(MM / MON)の混在
Oracleでは月指定方法が複数あります。
| フォーマット | 内容 |
|---|---|
| MM | 数値月(01〜12) |
| MON | 英語月略称(JANなど) |
| MONTH | 英語月名称 |
エラー例
|
1 |
TO_DATE('01-DEC-2024','YYYY-MM-DD') |
DECなのにMM指定しています。
修正
|
1 |
TO_DATE('01-DEC-2024','DD-MON-YYYY') |
原因⑤ DATE型をTO_DATEで再変換している
実務で非常に多いミスです。
DATE型カラムへTO_DATEを再度適用すると失敗します。
NG例
|
1 |
TO_DATE(CREATE_DATE,'YYYY-MM-DD') |
CREATE_DATEは既にDATE型です。
正しい方法
|
1 |
TO_CHAR(CREATE_DATE,'YYYY-MM-DD') |
表示目的の場合はTO_CHARを使用します。
ORA-01843を確実に防ぐ実務ルール
| ルール | 理由 |
|---|---|
| DATE型へ文字列を直接入れない | 暗黙変換防止 |
| 必ずTO_DATEを使用 | 環境差異回避 |
| フォーマット完全一致 | 区切り文字も対象 |
| NLS設定に依存しない | 本番障害防止 |
| DATE型は再変換しない | 型不整合防止 |
INSERT・UPDATEでの安全な記述テンプレート
INSERT
|
1 2 3 4 |
INSERT INTO TEST_TABLE (CREATE_DATE) VALUES (TO_DATE('2024-12-01','YYYY-MM-DD')); |
UPDATE
|
1 2 3 |
UPDATE TEST_TABLE SET CREATE_DATE = TO_DATE('2024-12-01','YYYY-MM-DD'); |
この書き方を統一するだけで、ORA-01843の大半は防止できます。
よくある質問(Q & A)
- 同じSQLなのに環境によってエラーが出ます
-
NLS_DATE_FORMATの設定差異が原因です。
暗黙変換をやめ、TO_DATEで明示変換してください。 - 月は正しいのにORA-01843が出ます
-
月そのものではなく、フォーマット不一致が原因です。
区切り文字や順序を確認してください。 - SYSDATEでも発生しますか?
-
SYSDATE自体では発生しません。
SYSDATEを文字列変換後に再変換すると発生する場合があります。 - Javaや外部システム連携時に多い理由は?
-
アプリ側の日付文字列形式とOracle側フォーマットが一致していないためです。
まとめ
ORA-01843は「月が無効」という表現ですが、実際の原因は日付フォーマット不一致です。
特に以下を徹底することで再発を防止できます。
・DATE型へ文字列を直接代入しない
・TO_DATEで明示変換する
・フォーマットを完全一致させる
・NLS_DATE_FORMATへ依存しない
Oracleの日付エラーは環境依存トラブルになりやすいため、SQL記述ルールを統一することが最も重要です。


