SQL日期转换结果为“无效数字格式模型参数”。

时间:2015-11-13 07:00:25

标签: sql oracle oracle11g date-formatting date-arithmetic

我必须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.

我对变量fromDatetoDate的输入只是日期字符串,例如20111010等。我还尝试了更具体的时间(与表中的格式相同),但是似乎不是问题..

在数据库中,CREATE_TIME列为TIMESTAMP(6)类型,例如一个样本为2011/12/19 08:04:42

出现错误的原因是什么?

2 个答案:

答案 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)

我希望这个解决方案有所帮助。

有太多不必要的转化。

我在我的系统中模拟了相同的场景,enter image description here

此处CREATED_TIME是一列数据类型timestamp(6)