日付フォーマットエラー
今私が仕事で作っているとあるシステムで、
エラーが発生しました。
ブラウザ上のINPUTフィールドに入力された
日付フォーマット文字列を
そのままSQLに投げる部分でこのエラーが発生した模様です。
ORA-01847: 月単位の日付は1から月末日の間で指定する必要があります
さて、このOracleのエラーが発生したわけですが、
これはたとえば "2006/5/32" とかみたいな
ありえない日付を入力されたときに起こるエラーです。
ところで今作っている日付フォーマットチェックは完璧にされているはずなんですが
どうしてこんなことが起こったんだろう?
データ受け渡しのBeanの詰め替えが失敗しているのかな?
ということでソースコードをひたすら追いかけていってみたら
以下のような部分を発見しました。
/* 作成日(To) */ str = bean.getSishkshnToDt(); if (str != null && false == str.equals("")) { list.add(str + "23:59:59.999999999"); //作成日(To) }
↓SQLのWHERE部分
str = bean.getSishkshnToDt(); if (str != null && false == str.equals("")) { conditionBuff.append(" AND b.sishkshn_dt <= TO_TIMESTAMP(?,'YYYY/MM/DDHH24:MI:SSxFF')"); //作成日(To) }
beanの項目sishkshnToDtに "23:59:59.999999999" を結合した文字列を
SQLのパラメータとして作成している部分なんですが、
これではまずいことに気が付きます。
もし、strの中身が"2006/5/3"のような日付だった場合、
結合した文字列は
"2006/5/323:59:59.999999999"となってしまい
これで晴れて"2006/5/32"という
無茶な日付が完成します。
回避作として以下のようにするといいみたいです。
list.add(str + " 23:59:59.999999999"); //作成日(To)
のように23の前に半角スペースを入れてあげると
Oracleさんはちゃんと動いてくれるみたいです。
このエラーの原因は日付フォーマットチェックを行った後に
文字列を結合してしまっている点にあります。
エラーチェックの際の順番は大事ですね。