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

两个日期必须进行比较,一个格式为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:不是有效的月份


由于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()因为它最终匹配列的数据类型(并且允许使用该列上的任何索引),并且不需要时间戳允许的小数秒精度; 由于您没有AM / PM指标,我也将HH更改为HH24


这是现在比较datedate 。 这里没有关系,因为你不需要额外的精度,但是如果你想把date转换为timestamp ,你不需要有一个中间的varchar2值,你可以使用CAST(PAYMENT_DATE AS TIMESTAMP)


以下工作完美:

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; 或者以其他方式与你的绑定变量做类似的事情来找到错误的日期......

哦,并且总是以日期或ISO格式存储日期 :XKCD

链接地址: http://www.djcxy.com/p/36953.html

上一篇: Comparison between dates in SQL using to

下一篇: Checking if date falls in a specified month in Oracle