查询1:冗余to_date用法:
SELECT 1
FROM dual
WHERE '22-APR-2018'>add_months(to_date(
(to_date('28-02-2018' ,'dd-mm-yyyy') ) ,'dd-mm-yyyy'),60);
-
查询2:单个to_date用法:
SELECT 1
FROM dual where '22-APR-2018'>ADD_MONTHS(TO_DATE('28-02-2018' ,'dd-mm-yyyy'),60);
在任何情况下,这些查询都不能返回数据,因为22-APR-2018永远不会超过28-FEB-2023。
但查询1 会返回数据。我不明白oracle的功能。
答案 0 :(得分:4)
此代码存在一些问题。其中之一是:
to_date((to_date('28-02-2018', 'dd-mm-yyyy')), 'dd-mm-yyyy')
或没有双重包围:
to_date(to_date('28-02-2018', 'dd-mm-yyyy'), 'dd-mm-yyyy')
to_date()
接受一个字符串参数,因此Oracle必须将它从to_date('28-02-2018', 'dd-mm-yyyy')
获得的日期转换为字符串。所以它是隐含的
to_date(to_char(to_date('28-02-2018', 'dd-mm-yyyy')), 'dd-mm-yyyy')
to_char(to_date('28-02-2018', 'dd-mm-yyyy'))
给你什么?这取决于您的nls_date_format
,通常默认为DD-MON-RR
,在这种情况下,您将获得28-FEB-18
,并将其转换回YYYY
年格式的日期0018年2月28日(Oracle隐含地将FEB
解释为匹配MM
),这是在2018年4月22日之前。
Oracle也会隐式地将比较中的字符串转换为日期,再次使用默认日期格式,所以尽管将字符串与日期进行比较并希望获得最佳效果显然是个坏主意,但在这种情况下,您可以放弃它
在Oracle中,我们将日期文字写为
date '2018-04-22'
而不是
'22-APR-2018'
所以写这个的正确方法是
select 1
from dual
where date '2018-04-22' > add_months(date '2018-02-28', 60);
,不提供任何行。
答案 1 :(得分:1)
'22 -APR-2018'不是date
它是一个字符串。因此,条件的两边都被隐式转换为字符串并且'APR'< 'FEB'。
在其上使用to_date
或(更简单地)使用ANSI文字,以便您比较date
值:
SELECT 1
FROM dual where DATE '2018-04-22'>ADD_MONTHS(TO_DATE('28-02-2018' ,'dd-mm-yyyy'),60);