_Oracle 11g
_データベースからいくつかのデータをselect
する必要がありますが、次のselect
クエリが失敗する理由を理解できないようです。
_SELECT
INFO_ID,
INFO_DETAIL,
IMPORTANT_FLG,
DELETE_FLG,
CREATE_TIME,
DISPLAY_ORDER
FROM TABLE_NAME
WHERE TO_DATE(TO_CHAR(CREATE_TIME, 'YYYY/MM/DD'), 'YYYY/MM/DD')
BETWEEN TO_DATE(TO_CHAR(:fromDate, 'YYYY/MM/DD'), 'YYYY/MM/DD') AND TO_DATE(TO_CHAR(:toDate, 'YYYY/MM/DD'), 'YYYY/MM/DD')
ORDER BY IMPORTANT_FLG DESC NULLS LAST , DISPLAY_ORDER ASC NULLS LAST, CREATE_TIME DESC, INFO_ID ASC
_
クエリは次のエラーメッセージで失敗します:
_ORA-01481: invalid number format model
01481. 00000 - "invalid number format model"
*Cause: The user is attempting to either convert a number to a string
via TO_CHAR or a string to a number via TO_NUMBER and has
supplied an invalid number format model parameter.
_
変数fromDate
とtoDate
の入力は、_20111010
_などの日付文字列です。より具体的な時刻(表と同じ形式)も試しましたが、問題はないようです。
データベースでは、_CREATE_TIME
_列はTIMESTAMP(6)
タイプであり、たとえば、1つのサンプルは_2011/12/19 08:04:42
_です。
これがエラーである理由は何か考えが浮かびますか?
根本原因:
[〜#〜] number [〜#〜]を[〜#〜] string [〜#〜]に変換していますが、[〜#〜]日付[〜#〜]。 _20111010
_は日付ではなく、数値です。また、_'20111010'
_は日付ではなく、文字列です。それらは完全に異なります。
20111010
_ --[〜#〜] number [〜#〜]'20111010'
_ --[〜#〜] string [〜#〜]TO_DATE('20111010','YYYYMMDD')
--[〜#〜] date [〜#〜]エラー:
_SQL> SELECT TO_CHAR(20111010, 'YYYY/MM/DD') FROM dual;
SELECT TO_CHAR(20111010, 'YYYY/MM/DD') FROM dual
*
ERROR at line 1:
ORA-01481: invalid number format model
_
あなたの質問に来る:
_WHERE TO_DATE(TO_CHAR(CREATE_TIME, 'YYYY/MM/DD'), 'YYYY/MM/DD')
BETWEEN TO_DATE(TO_CHAR(:fromDate, 'YYYY/MM/DD'), 'YYYY/MM/DD')
AND TO_DATE(TO_CHAR(:toDate, 'YYYY/MM/DD'), 'YYYY/MM/DD')
_
変換とフォーマットが不必要に複雑になっています。
[〜#〜] timestamp [〜#〜]データ型は、[〜#〜] date [〜#〜]データ型の拡張です。 DATEデータ型のdatetime要素に加えて、TIMESTAMPデータ型は、小数点以下0桁から9桁までの精度で秒の小数部を保持します。デフォルトは6です。
データベースでは、CREATE_TIME列はTIMESTAMP(6)タイプであり、たとえば1つのサンプルは2011/12/1908:04:42です。
[〜#〜] timestamp [〜#〜]を扱っているので、TO_TIMESTAMPを使用できます。
DATE/TIMESTAMP演算を実行している間は、データ型をそのままにして、stringに変換しないでください。 TO_CHARはdisplayにのみ使用する必要があります。
フィルタ述語を次のように変更します。
_WHERE CREATE_TIME
BETWEEN TO_TIMESTAMP(:fromDate, 'YYYY/MM/DD')
AND TO_TIMESTAMP(:toDate, 'YYYY/MM/DD')
_
上記では、_:fromDate
_および_:toDate
_はstringであり、numberではありません。
例えば、
_SQL> SELECT to_timestamp('20111010', 'YYYYMMDD') FROM dual;
TO_TIMESTAMP('20111010','YYYYMMDD')
-----------------------------------------------------------
10-OCT-11 12.00.00.000000000 AM
_
または、TO_CHARを使用して最初にconvertnumber into string:
_SQL> SELECT to_timestamp(TO_CHAR(20111010), 'YYYYMMDD') FROM dual;
TO_TIMESTAMP(TO_CHAR(20111010),'YYYYMMDD')
------------------------------------------------------------------
10-OCT-11 12.00.00.000000000 AM
_