Oracle日期格式问题

Trouble with Oracle date format

查询 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);

无论如何,这些查询不得 return 数据,因为 22-APR-2018 永远不会大于 28-FEB-2023。

但是查询了1returns条数据。我不明白这里的 oracle 功能。

'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);

此代码存在一些问题。其中之一是:

to_date((to_date('28-02-2018', 'dd-mm-yyyy')), 'dd-mm-yyyy')

或没有 double-bracketing:

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 年份格式的日期给出 28th Feb 0018(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);

没有行。