SQL 日期转换结果为 "invalid number format model parameter."

SQL date conversion results to "invalid number format model parameter."

我必须 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 等。我也尝试了更具体的时间(与 [=33 中的格式相同) =]), 但这似乎不是问题..

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

知道为什么会弹出这个错误吗?

根本原因:

您正在将 NUMBER 转换为 STRING,假设它是 DATE20111010 不是日期,而是数字。此外,'20111010' 不是日期,而是字符串。他们是完全不同的。

  • 20111010 - NUMBER
  • '20111010' - STRING
  • TO_DATE('20111010','YYYYMMDD') - 日期

错误:

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 数据类型的日期时间元素外,TIMESTAMP 数据类型还保存小数秒,精度在小数点后 0 到 9 位之间,默认为 6。

In the database the CREATE_TIME column is TIMESTAMP(6) type, and for example one sample is 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 应该是 string 而不是 number.

例如,

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

希望此解决方案对您有所帮助。

不必要的转换太多。

我已经在我的系统中模拟了相同的场景,

此处 CREATED_TIME 是一个数据类型为 timestamp(6) 的列。