使用to_timestamp在SQL中的日期之间的比较

时间:2014-11-20 10:01:28

标签: sql oracle date

必须比较两个日期,一个是MM / DD / YYYY格式,另一个是YYYY / MM / DD HH:MI:SS。

如何做到这一点。我尝试使用to_timestamp,但它抛出的错误如下:

  AND TO_TIMESTAMP(PAYMENT_DATE,'MM/DD/YYYY HH:MI:SS')>=TO_TIMESTAMP( :L_RESEND_DATE,'YYYY/MM/DD HH:MI:SS')

[错误]执行(23:27):ORA-01843:不是有效月份

2 个答案:

答案 0 :(得分:2)

由于payment_date已经是date类型,因此您不需要也不应该转换它。您正在根据您的NLS设置进行从datevarchar2的隐式转换,然后使用您指定的格式模型进行显式转换,并且如a_horse_with_no_name所述,这既无意义又容易出错。所以你有效地做了:

TO_TIMESTAMP(TO_CHAR(PAYMENT_DATE, <NLS_DATE_FORMAT>),'MM/DD/YYYY HH:MI:SS')

例如,如果你的会话的NLS_DATE_FORMAT是DD / MM / YYYY,那意味着你正在做:

TO_TIMESTAMP(TO_CHAR(PAYMENT_DATE, 'DD/MM/YYYY'),'MM/DD/YYYY HH:MI:SS')

...并尝试交换月份和日期数字,这可以解释您的错误。只要您的日期数大于12,双重转换就会出错,即使没有引发任何错误,其他值也会不正确。

根本不要转换表格列,只需转换参数:

AND PAYMENT_DATE >= TO_DATE(:L_RESEND_DATE, 'YYYY/MM/DD HH24:MI:SS')

我使用to_date()而不是to_timestamp(),因为它最终匹配列的数据类型(并允许使用该列上的任何索引),并且您不需要小数秒时间戳允许的精度;我还将HH更改为HH24,因为您没有AM / PM指示符。


现在将datedate进行比较。这里不相关,因为您不需要额外的精度,但如果您确实想要将date转换为timestamp,则不需要具有中间{{1} }}},您可以使用varchar2代替CAST(PAYMENT_DATE AS TIMESTAMP)

答案 1 :(得分:1)

以下作品完美无缺:

SELECT 1 FROM DUAL
 WHERE TO_TIMESTAMP('11/23/2014 10:32:15','MM/DD/YYYY HH:MI:SS')
       >=
       TO_TIMESTAMP( '2013/11/29 12:54:12','YYYY/MM/DD HH:MI:SS');

所以解决方案很简单 - 很可能你的数据是错误的...很可能你的某些日期是DD / MM / YYYY或YYYY / DD / MM - 如果有疑问则相信错误信息,这是非常精确的并且清楚 - 你有一个超出范围的月值; - )

也许尝试SELECT * FROM ... WHERE TO_NUMBER(SUBSTR(PAYMENT_DATE,1,2)) > 12;或者用你的bind-variable做类似的事情来查找错误的日期......

哦和始终将日期作为日期或ISO格式存储XKCD