我必须select
来自Oracle 11g
数据库的一些数据,但我似乎无法弄清楚为什么跟随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)
类型,例如一个样本为2011/12/19 08:04:42
出现错误的原因是什么?
答案 0 :(得分:7)
根本原因:
您正在将 NUMBER 转换为 STRING ,假设它是 DATE 。 20111010
不是DATE,而是NUMBER。此外,'20111010'
不是DATE,它是STRING。它们完全不同。
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)类型,例如一个样本是2011/12/19 08:04:42
由于您正在处理 TIMESTAMP ,因此您可以使用 TO_TIMESTAMP 。
在执行 DATE / TIMESTAMP算术时,您应保留数据类型,而不是将其转换为字符串。您只需将 TO_CHAR 用于显示。
将过滤谓词修改为:
WHERE CREATE_TIME
BETWEEN TO_TIMESTAMP(:fromDate, 'YYYY/MM/DD')
AND TO_TIMESTAMP(:toDate, 'YYYY/MM/DD')
以上,:fromDate
和:toDate
应为字符串,而不是数字。
例如,
SQL> SELECT to_timestamp('20111010', 'YYYYMMDD') FROM dual;
TO_TIMESTAMP('20111010','YYYYMMDD')
-----------------------------------------------------------
10-OCT-11 12.00.00.000000000 AM
或者,使用 TO_CHAR 首先转换 数字到字符串:
SQL> SELECT to_timestamp(TO_CHAR(20111010), 'YYYYMMDD') FROM dual;
TO_TIMESTAMP(TO_CHAR(20111010),'YYYYMMDD')
------------------------------------------------------------------
10-OCT-11 12.00.00.000000000 AM
答案 1 :(得分:3)