Oracle SQL:使用to_date时年份输出错误

时间:2019-06-24 06:26:06

标签: sql oracle

我正在为报告编写Oracle SQL语句。 用户可以输入FROM / TO日期,我将其与(简化)的已发布行进行比较:

… where changedate < to_date(user_input, 'dd.MM.YYYY')…

字段“ changedate”是此表中的数据类型DATE。

代码:

select to_date(changedate, 'dd.MM.YYYY') from TICKETSTATUS;

该字段通常包含

30.03.2019 21:50:48

但是我将输出与代码转换的输出是:

30.03.0019

为什么要这样做?我希望将“ 2019”作为年份,但似乎抹掉了前两个数字? 有人可以解释并帮助我解决该问题吗? 谢谢!

2 个答案:

答案 0 :(得分:2)

尝试使用两种格式的rrrryyyy插入年份值,以查看差异:

create table ticketstatus( id int, changedate date );
insert into ticketstatus values(1,to_date('30.03.19','dd.mm.yyyy'));
insert into ticketstatus values(2,to_date('31.03.19','dd.mm.rrrr'));

select changedate
  from ticketstatus;

CHANGEDATE
------------ 
30.03.0019   
31.03.2019

实际上,您可以观察到以下这种通用情况:

with ticketstatus(changedate) as
(
 select '30.03.19' from dual
)
select to_date(changedate,'dd.mm.yyyy') date_with_yy,
       to_date(changedate,'dd.mm.rrrr') date_with_rr
  from ticketstatus;

DATE_WITH_YY    DATE_WITH_RR
------------    ------------
30.03.0019      30.03.2019

这被称为Year 2k problem,年份格式rrrr正是由于这个问题。因此,可以将带有rrrr的日期格式用于此类问题。

答案 1 :(得分:2)

[TL; DR]

  1. 请勿在{{1​​}}数据类型上使用TO_DATE
  2. 您的问题可能出在数据输入上,而不是输出上,因为当预期为4位数字的年份时,您可能会获得2位数字的年份输入。

您不需要使用DATEchange_date转换为DATE,因为它已经是TO_DATE数据类型。只需使用:

DATE

如果您希望日期值具有特定格式,请使用select changedate from TICKETSTATUS; (而不是TO_CHAR):

TO_DATE
  

但是我的输出[]是:

SELECT TO_CHAR( changedate, 'dd.mm.yyyy' )
FROM   TICKETSTATUS;

这可能是因为您在代码中的其他地方出现了错误,该错误可能是从带有2位数字年份的字符串中插入日期,而预期是4位数字年份。

30.03.0019

那年将是CREATE TABLE TicketStatus ( changedate DATE ); INSERT INTO TicketStatus ( changedate ) VALUES ( TO_DATE( '30.03.19', 'dd.mm.yyyy' ) );

但是,如果您使用0019格式模型已经好几年了(或者视情况而定,使用RR格式模型):

YY

那年将是INSERT INTO TicketStatus ( changedate ) VALUES ( TO_DATE( '30.03.19', 'dd.mm.rr' ) );

2019

输出:

| TO_CHAR(CHANGEDATE,'DD.MM.YYYY') |
| :------------------------------- |
| 30.03.0019                       |
| 30.03.2019                       |

db <>提琴here

也可能是因为您会话中的SELECT TO_CHAR( changedate, 'dd.mm.yyyy' ) FROM TicketStatus 设置为NLS_DATE_SETTING,并且在日期列上使用dd.mm.yy进行的隐式转换正在删除世纪,但随后 ALL 您的日期将具有世纪TO_DATE(而不仅仅是某些日期)。