【Oracle】ORA-01830の原因と解決方法|date format picture ends before converting entire input string

【Oracle】ORA-01830の原因と解決方法|date format picture ends before converting entire input string Oracle

ORA-01830: date format picture ends before converting entire input string は、Oracleで日付文字列を TO_DATETO_TIMESTAMP で変換するとき、指定したフォーマットが入力文字列の途中までしか読み取れず、文字列の後ろに余りが残った場合に発生するエラーです。

よくあるのは、入力値が 2026-05-13 10:30:00 のように時刻まで持っているのに、フォーマットを YYYY-MM-DD までしか指定していないケースです。日付部分は読めますが、後ろの 10:30:00 が余るためORA-01830になります。

先に結論
ORA-01830は、入力文字列とフォーマットモデルの長さ・要素を完全に合わせると直ります。時刻があるなら HH24:MI:SS、小数秒があるなら FF、タイムゾーンがあるなら TZH:TZM などを追加します。日付だけが欲しい場合は、文字列を先に切り詰めるのではなく、入力仕様やカラム型に合う変換を選びます。
スポンサーリンク

ORA-01830とは

Oracle公式の説明では、ORA-01830は、有効な日付フォーマットで先頭部分は変換できたものの、入力文字列全体を変換し終える前にフォーマットが終わってしまった状態です。つまり、入力文字列に対してフォーマット指定が短い、または要素が足りないと考えるとわかりやすいです。

日付フォーマットの基本は OracleのTO_CHAR / TO_DATE日付フォーマット、似たエラーの ORA-01861ORA-01861の原因と解決方法 も確認してください。

入力文字列 指定フォーマット 結果
2026-05-13 YYYY-MM-DD OK
2026-05-13 10:30:00 YYYY-MM-DD NG: 時刻部分が余る
2026-05-13 10:30:00 YYYY-MM-DD HH24:MI:SS OK
2026-05-13 10:30:00.123 YYYY-MM-DD HH24:MI:SS NG: 小数秒が余る

エラーが出たSQLを直す順番

ORA-01830は、エラー文だけを見ると抽象的ですが、直す順番はほぼ決まっています。まず実際に渡している文字列を確認し、次にフォーマットモデルがその文字列の最後の1文字まで対応しているかを見ます。最後に、保存先や比較対象のカラム型が DATE なのか TIMESTAMP なのかを合わせます。

  1. 入力値に時刻・小数秒・タイムゾーンが残っていないか確認する
  2. YYYYMMDDHH24MISSFF の不足を探す
  3. 日付だけ欲しい場合は、変換後に TRUNC するか、入力仕様を日付だけに寄せる
  4. 暗黙変換に任せず、TO_DATE / TO_TIMESTAMP / TO_TIMESTAMP_TZ を明示する

まず入力文字列とフォーマットを並べて確認する

ORA-01830を直す最短手順は、入力文字列とフォーマットモデルを横に並べて、最後まで対応しているか確認することです。入力に時刻、小数秒、タイムゾーン、区切り文字があるのに、フォーマット側に対応する要素がなければエラーになります。

入力側の要素 フォーマット側の例 補足
YYYY 4桁年
MM 2桁月
DD 2桁日
HH24 24時間表記
MI 分。月のMMと混同しない
SS
小数秒 FF TO_TIMESTAMPで扱う
タイムゾーン TZH:TZM +09:00など

時刻があるのにYYYY-MM-DDだけ指定しているケース

もっとも多い原因は、入力値に時刻が含まれているのに、フォーマットが日付部分だけになっているケースです。

time-part-leftover.sql
-- NG: 入力には時刻があるが、フォーマットは日付まで
SELECT TO_DATE('2026-05-13 10:30:00', 'YYYY-MM-DD')
FROM dual;

-- OK: 入力文字列全体に合わせる
SELECT TO_DATE('2026-05-13 10:30:00', 'YYYY-MM-DD HH24:MI:SS')
FROM dual;

時刻を切り捨てて日付だけで扱いたい場合も、まず正しく変換してから TRUNC するのが安全です。日付の切り捨ては OracleのTRUNC関数で日付を切り捨てる方法 にまとめています。

convert-then-trunc.sql
SELECT TRUNC(TO_DATE('2026-05-13 10:30:00', 'YYYY-MM-DD HH24:MI:SS')) AS order_date
FROM dual;

小数秒がある場合はTO_TIMESTAMPを使う

入力文字列に .123.463779 のような小数秒が含まれる場合、TO_DATE ではなく TO_TIMESTAMP を使うのが自然です。フォーマットには FF を指定します。

fractional-seconds.sql
-- NG: 小数秒 .123 が余る
SELECT TO_DATE('2026-05-13 10:30:00.123', 'YYYY-MM-DD HH24:MI:SS')
FROM dual;

-- OK: TIMESTAMPとして小数秒まで読む
SELECT TO_TIMESTAMP('2026-05-13 10:30:00.123', 'YYYY-MM-DD HH24:MI:SS.FF')
FROM dual;

カラムが DATE 型なら秒まで、TIMESTAMP 型なら小数秒まで扱えます。入力値の精度と保存先の型を合わせて考えます。

タイムゾーン付き文字列のケース

2026-05-13 10:30:00 +09:00 のようにタイムゾーンが付いている場合、通常の TO_DATETO_TIMESTAMP では後ろのタイムゾーン部分が余ることがあります。タイムゾーンまで扱うなら TO_TIMESTAMP_TZ を検討します。

timestamp-timezone.sql
SELECT TO_TIMESTAMP_TZ(
           '2026-05-13 10:30:00 +09:00',
           'YYYY-MM-DD HH24:MI:SS TZH:TZM'
       ) AS created_at
FROM dual;

WHERE句で文字列日付を比較しているケース

Java、PHP、バッチなどからSQLを組み立てるとき、日付カラムと文字列をそのまま比較してORA-01830になることがあります。Oracleが暗黙変換を行い、セッションの NLS_DATE_FORMAT と入力文字列が合わないためです。

implicit-date-conversion.sql
-- NG: 文字列が暗黙変換され、環境によってORA-01830になる
SELECT *
FROM orders
WHERE order_date >= '2026-05-13 00:00:00';

-- OK: TO_DATEで明示的に変換する
SELECT *
FROM orders
WHERE order_date >= TO_DATE('2026-05-13 00:00:00', 'YYYY-MM-DD HH24:MI:SS');

時刻が不要な日付だけの比較なら、DATEリテラルも使えます。現在日時や日付関数の基本は SYSDATE・SYSTIMESTAMPの違い も参考になります。

date-literal.sql
SELECT *
FROM orders
WHERE order_date >= DATE '2026-05-13';

INSERTで発生するケース

INSERTでも、日付カラムに文字列を入れると暗黙変換やフォーマット不一致でORA-01830になることがあります。入力値の形式を明示してから登録します。

insert-date-string.sql
-- NG: 文字列のままDATE列へ入れている
INSERT INTO orders (order_id, order_date)
VALUES (1, '2026-05-13 10:30:00');

-- OK: 形式を明示する
INSERT INTO orders (order_id, order_date)
VALUES (1, TO_DATE('2026-05-13 10:30:00', 'YYYY-MM-DD HH24:MI:SS'));

TO_CHARしてからTO_DATEし直す時の注意

既にDATEやTIMESTAMPとして持っている値を TO_CHAR し、さらに TO_DATE し直す処理でもORA-01830が起きます。文字列化したフォーマットと、読み戻すフォーマットが一致していないためです。

to-char-to-date-mismatch.sql
-- NG: TO_CHARでは時刻まで出しているが、TO_DATEは日付までしか読まない
SELECT TO_DATE(
           TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS.FF'),
           'YYYY-MM-DD'
       )
FROM dual;

-- OK: 文字列化と読み戻しのフォーマットを合わせる
SELECT TO_TIMESTAMP(
           TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS.FF'),
           'YYYY-MM-DD HH24:MI:SS.FF'
       )
FROM dual;

そもそも日付型のまま処理できるなら、文字列に変換して戻す処理は避けたほうが安全です。表示のための TO_CHAR と、比較・保存のための日付型処理は分けて考えます。

ORA-01861との違い

ORA-01830ORA-01861 はどちらも日付フォーマット不一致で発生しますが、見方が少し違います。ORA-01830は「先頭は読めたが、入力文字列の後ろが余った」ケース、ORA-01861は「文字列とフォーマットがそもそも合っていない」ケースとして切り分けると調査しやすいです。

エラー 典型例 主な直し方
ORA-01830 2026-05-13 10:30:00YYYY-MM-DD 時刻など不足している書式要素を足す
ORA-01861 2026/05/13YYYY-MM-DD 区切り文字や月表記などを入力に合わせる

NLS_DATE_FORMATに依存しない

開発環境では動くのに本番や別ツールでORA-01830になる場合、暗黙変換と NLS_DATE_FORMAT の違いが原因のことがあります。SQL Developer、TOAD、JDBC、バッチでセッション設定が違うと、同じ文字列でも変換結果が変わります。

check-nls-date-format.sql
SELECT value
FROM nls_session_parameters
WHERE parameter = 'NLS_DATE_FORMAT';

アプリやバッチでは、NLS設定に頼らず TO_DATETO_TIMESTAMP、DATEリテラル、バインド変数を使って明示的に渡すのが安全です。

修正チェックリスト

手順 確認すること 見るポイント
1 入力文字列をそのまま確認する 時刻・小数秒・タイムゾーンが付いていないか
2 フォーマットモデルを確認する 入力末尾まで読める要素があるか
3 DATEかTIMESTAMPか確認する 小数秒があるならTO_TIMESTAMPを検討する
4 暗黙変換を避ける 文字列比較ではなくTO_DATEやDATEリテラルを使う
5 TO_CHARとTO_DATEの往復を見直す 文字列化と読み戻しの書式が一致しているか
6 ORA-01861と切り分ける 余りがあるのか、最初から合っていないのか
7 NLS設定に依存していないか確認する 環境差で再発しないようにする

よくある質問

ORA-01830はなぜ時刻付き文字列で起きやすいですか?

入力には時刻まであるのに、フォーマットが日付までしかないケースが多いためです。YYYY-MM-DD HH24:MI:SS のように、入力文字列全体に合わせて指定します。

日付だけ欲しい場合、SUBSTRで先頭10文字にしてよいですか?

一時対応として使われることはありますが、入力形式が変わると壊れやすいです。まず正しい型へ変換し、必要なら TRUNC で日付部分にそろえる方が安全です。

TO_DATEとTO_TIMESTAMPはどう使い分けますか?

秒までのDATE値なら TO_DATE、小数秒まで扱うなら TO_TIMESTAMP、タイムゾーンまで扱うなら TO_TIMESTAMP_TZ を検討します。

DATE型に時刻は入りますか?

OracleのDATE型は年月日だけでなく時分秒も保持します。ただし小数秒は保持しないため、小数秒が必要ならTIMESTAMP型を使います。

NLS_DATE_FORMATを変えれば解決しますか?

一時的に動くことはありますが、環境依存になりやすいです。アプリやバッチでは、フォーマットを明示するか、日付型のバインド変数で渡すのが安全です。

まとめ

ORA-01830は、入力日付文字列を変換する途中でフォーマットモデルが先に終わり、文字列の後ろに余りが残ったときに発生します。まず入力文字列とフォーマットを並べて、時刻、小数秒、タイムゾーンなどが不足していないか確認します。

時刻があるなら HH24:MI:SS、小数秒があるなら TO_TIMESTAMPFF、タイムゾーンがあるなら TO_TIMESTAMP_TZ を使います。暗黙変換やNLS設定に頼らず、入力仕様に合った明示的な変換にすることが再発防止になります。

参考

ORA-01830 – Oracle Database Error Help

Format Models – Oracle SQL Language Reference