简体   繁体   English

Oracle日期格式出现问题

[英]Trouble with Oracle date format

Query 1: Redundant to_date usage: 查询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);

-- -

Query 2: Single to_date usage: 查询2:单个to_date用法:

SELECT 1
FROM dual where '22-APR-2018'>ADD_MONTHS(TO_DATE('28-02-2018' ,'dd-mm-yyyy'),60);

In any case, these queries must not return data, since 22-APR-2018 is never greater than 28-FEB-2023. 在任何情况下,这些查询都不得返回数据,因为2018年4月22日永远不会大于28年2月2日。

But Query 1 returns data. 但是查询1返回数据。 I do not understand oracle functionality here. 我在这里不了解oracle功能。

There are a few issues with this code. 此代码存在一些问题。 One of them is: 其中之一是:

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

or without the double-bracketing: 或不使用双括号:

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

to_date() takes a string argument, so Oracle has to convert the date it got from to_date('28-02-2018', 'dd-mm-yyyy') into a string. to_date()采用字符串参数,因此Oracle必须将其从to_date('28-02-2018', 'dd-mm-yyyy')转换为字符串。 So implicitly it's 所以暗含

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

What does to_char(to_date('28-02-2018', 'dd-mm-yyyy')) give you? to_char(to_date('28-02-2018', 'dd-mm-yyyy'))给你什么? It will depend on your nls_date_format , which often defaults to DD-MON-RR , in which case you'll get 28-FEB-18 , and converting that back to a date with a YYYY year format gives 28th Feb 0018 (Oracle implicitly interprets FEB to match MM ), which is before 22nd April 2018. 这取决于您的nls_date_format (通常默认为DD-MON-RR ,在这种情况下,您将获得28-FEB-18 ,并将其转换回具有YYYY年格式的日期将得到2818 Feb 0018(Oracle隐式解释为FEB以匹配MM ),这是在2018年4月22日之前。

Oracle also implicitly converts the string in the comparison to a date, again using the default date format, so although it's obviously a bad idea to compare a string to a date and hope for the best, in this case you get away with it. Oracle还再次使用默认的日期格式将比较中的字符串隐式转换为日期,因此尽管将字符串与日期进行比较显然是个坏主意,并且希望获得最佳结果,但在这种情况下,您还是可以避免使用它。

In Oracle we write date literals as 在Oracle中,我们将日期文字写为

date '2018-04-22'

and not 并不是

'22-APR-2018'

So the right way to write this would be 所以写这个的正确方法是

select 1
from   dual
where  date '2018-04-22' > add_months(date '2018-02-28', 60);

which gives no rows. 没有任何行。

'22-APR-2018' is not a date it is a string. '22 -APR-2018'不是date它是一个字符串。 So both sides of the condition get implicitly converted to strings and 'APR' < 'FEB'. 因此,条件的两侧都隐式转换为字符串,并且'APR'<'FEB'。

Use to_date on it or (easier) an ANSI literal instead so that you are comparing date values: 在上面使用to_date或(更容易)ANSI文字,以便您比较date值:

SELECT 1
FROM dual where DATE '2018-04-22'>ADD_MONTHS(TO_DATE('28-02-2018' ,'dd-mm-yyyy'),60);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM