Oracle Database を使っていると、日付や時刻を扱うSQLで頻繁に遭遇するのが ORA-01861 エラーです。
本記事では、エラーの意味 → よくある原因 → 実践的な対処法 → 再発防止策 の順で、現場向けに分かりやすく解説します。
ORA-01861 とは?
|
1 |
ORA-01861: リテラルが書式文字列と一致しません |
このエラーは、SQLで指定した値(リテラル)と、Oracleが期待している日付・時刻の書式が一致していない 場合に発生します。
特に以下のようなケースで起こりがちです。
- 文字列を日付として比較している
TO_DATEの書式が間違っている- セッションの
NLS_DATE_FORMATに依存している
よくある原因①:文字列のまま日付と比較している
❌ NG例(よくある)
|
1 2 3 |
SELECT * FROM orders WHERE order_date = '2024-01-01'; |
order_date が DATE 型の場合、
文字列 '2024-01-01' は自動変換され、その際に書式不一致が起きる 可能性があります。
✅ 正しい書き方
|
1 2 3 |
SELECT * FROM orders WHERE order_date = TO_DATE('2024-01-01', 'YYYY-MM-DD'); |
👉 日付は必ず TO_DATE で明示的に変換する のが基本です。
よくある原因②:TO_DATE の書式指定ミス
❌ NG例(書式が合っていない)
|
1 2 |
SELECT TO_DATE('20240101', 'YYYY-MM-DD') FROM dual; |
- 実データ:
20240101 - 指定書式:
YYYY-MM-DD
➡ 当然一致せず ORA-01861 が発生します。
✅ 正しい書き方
|
1 2 |
SELECT TO_DATE('20240101', 'YYYYMMDD') FROM dual; |
リテラルの文字列と書式は「完全一致」している必要があります。
よくある原因③:時刻を含む DATE の比較
Oracle の DATE 型は 日付+時刻 を持っています。
❌ NG例
|
1 2 3 |
SELECT * FROM orders WHERE order_date = TO_DATE('2024-01-01', 'YYYY-MM-DD'); |
order_date が2024-01-01 10:30:00 のような値だと 一致しません。
✅ 対処法①:範囲指定(推奨)
|
1 2 3 4 |
SELECT * FROM orders WHERE order_date >= TO_DATE('2024-01-01', 'YYYY-MM-DD') AND order_date < TO_DATE('2024-01-02', 'YYYY-MM-DD'); |
👉 日付検索で最も安全な方法 です。
✅ 対処法②:TRUNC を使う(注意あり)
|
1 2 3 |
SELECT * FROM orders WHERE TRUNC(order_date) = TO_DATE('2024-01-01', 'YYYY-MM-DD'); |
⚠ TRUNC を使うと インデックスが効かなくなる 場合があるため注意。
よくある原因④:NLS_DATE_FORMAT 依存
セッションの設定確認
|
1 2 3 |
SELECT value FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT'; |
例:
YYYY/MM/DD
この状態で以下を書くと…
|
1 2 3 |
SELECT * FROM orders WHERE order_date = '2024-01-01'; |
➡ / と - の違いで ORA-01861 が発生します。
✅ 回避策(最重要)
- 暗黙の型変換に頼らない
- 必ず
TO_DATEを使う
INSERT / UPDATE 時の注意点
❌ NG例
|
1 2 |
INSERT INTO orders (order_date) VALUES ('2024-01-01'); |
✅ 正しい書き方
|
1 2 |
INSERT INTO orders (order_date) VALUES (TO_DATE('2024-01-01', 'YYYY-MM-DD')); |
再発防止のベストプラクティス
✅ 日付は必ず TO_DATE / TO_TIMESTAMP を使う
✅ 書式は文字列と完全一致させる
✅ DATE 型の比較は範囲指定を基本にする
✅ NLS 設定に依存したSQLを書かない
まとめ
| ポイント | 内容 |
|---|---|
| エラー原因 | リテラルと日付書式の不一致 |
| よくある罠 | 暗黙の型変換・時刻付き DATE |
| 対処法 | TO_DATE 明示・範囲検索 |
| 重要度 | ★★★★★(超頻出) |
ORA-01861 は 一度理解すれば確実に防げるエラー です。
日付を扱うSQLでは、ぜひ本記事の書き方をテンプレとして使ってください。
