必须比较两个日期,一个是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:不是有效月份
答案 0 :(得分:2)
由于payment_date
已经是date
类型,因此您不需要也不应该转换它。您正在根据您的NLS设置进行从date
到varchar2
的隐式转换,然后使用您指定的格式模型进行显式转换,并且如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指示符。
现在将date
与date
进行比较。这里不相关,因为您不需要额外的精度,但如果您确实想要将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