Oracle中的日期格式问题
Date format issue in Oracle
在我们的 package
中,我们有如下 where
子句。
pp.start_date >= nvl(TO_DATE('01-JAN-2018', 'RRRR/MM/DD HH24:MI:SS'), pp.start_date)
它在客户环境中运行良好。但是由于格式是 'RRRR/MM/DD HH24:MI:SS'
所以我们像下面这样更改了日期。
pp.start_date >= nvl(TO_DATE('2018/01/01', 'RRRR/MM/DD HH24:MI:SS'), pp.start_date)
理想情况下它应该可以工作,因为我们提供了正确的格式。在第一种情况下,它返回 679 行,但在第二种情况下,它返回 0 行。我们有 679 个正确的行数。
第二个 NVL 命令有什么问题?
在我看来,两者都是错误的。
如果日期值是2018/01/01
,那么它的格式是(我推测)yyyy/mm/dd
(也可能是yyyy/dd/mm
,光看是看不出来的)。 hh24:mi:ss
格式从何而来?你没用过。
因此,我会使用日期文字(始终是 date 'yyyy-mm-dd'
)(因为您对时间分量不感兴趣):
where pp.start_date >= date '2018-01-01'
无NVL
功能。为什么?因为日期文字不能是 NULL
.
你会使用NVL
,如果它是关于其他一些专栏的,例如
where pp.start_date >= nvl(a.some_date, date '2018-01-01')
这意味着:如果 a.some_date
列是 NULL
,请改用 date '2018-01-01'
。
[编辑] 毕竟,如果有时间分量,请使用具有适当格式掩码的 TO_DATE
函数,例如
where pp.start_date >= to_date('2018-01-01 23:09', 'yyyy-mm-dd hh24:mi')
如果你这样做:
SELECT TO_DATE('01-JAN-2018', 'RRRR/MM/DD HH24:MI:SS')
FROM DUAL;
然后,从 string-to-date conversion rules:
RRRR
也匹配 RR
,后者匹配 01
,所以年份是 2001。
MM
也匹配 MON
匹配 JAN
.
DD
匹配 20
.
HH24
匹配 18
.
- 所以生成的日期是
2001-01-20 18:00:00
如果您使用:
SELECT TO_DATE('2018/01/01', 'RRRR/MM/DD HH24:MI:SS')
FROM DUAL;
然后:
RRRR
匹配 2018
.
MM
匹配 01
.
DD
匹配 01
.
- 所以生成的日期是
2018-01-01 00:00:00
sqlfiddle here
您生成的是两个完全不同的日期,相隔将近 17 年。
In the first case it is returning 679 rows but in second case it is returning 0 rows. 679 correct number of rows we have.
在第一种情况下,您将获得 2001-01-20T18:00:00
.
之后的 679 行
在第二种情况下,您将获得 2018-01-01T00:00:00
.
之后的 0 行
鉴于使用的日期分别是 01-JAN-2018
和 2018-01-01
,我认为第二个是正确的,你应该得到 0 行而不是 679 行。
在我们的 package
中,我们有如下 where
子句。
pp.start_date >= nvl(TO_DATE('01-JAN-2018', 'RRRR/MM/DD HH24:MI:SS'), pp.start_date)
它在客户环境中运行良好。但是由于格式是 'RRRR/MM/DD HH24:MI:SS'
所以我们像下面这样更改了日期。
pp.start_date >= nvl(TO_DATE('2018/01/01', 'RRRR/MM/DD HH24:MI:SS'), pp.start_date)
理想情况下它应该可以工作,因为我们提供了正确的格式。在第一种情况下,它返回 679 行,但在第二种情况下,它返回 0 行。我们有 679 个正确的行数。
第二个 NVL 命令有什么问题?
在我看来,两者都是错误的。
如果日期值是2018/01/01
,那么它的格式是(我推测)yyyy/mm/dd
(也可能是yyyy/dd/mm
,光看是看不出来的)。 hh24:mi:ss
格式从何而来?你没用过。
因此,我会使用日期文字(始终是 date 'yyyy-mm-dd'
)(因为您对时间分量不感兴趣):
where pp.start_date >= date '2018-01-01'
无NVL
功能。为什么?因为日期文字不能是 NULL
.
你会使用NVL
,如果它是关于其他一些专栏的,例如
where pp.start_date >= nvl(a.some_date, date '2018-01-01')
这意味着:如果 a.some_date
列是 NULL
,请改用 date '2018-01-01'
。
[编辑] 毕竟,如果有时间分量,请使用具有适当格式掩码的 TO_DATE
函数,例如
where pp.start_date >= to_date('2018-01-01 23:09', 'yyyy-mm-dd hh24:mi')
如果你这样做:
SELECT TO_DATE('01-JAN-2018', 'RRRR/MM/DD HH24:MI:SS')
FROM DUAL;
然后,从 string-to-date conversion rules:
RRRR
也匹配RR
,后者匹配01
,所以年份是 2001。MM
也匹配MON
匹配JAN
.DD
匹配20
.HH24
匹配18
.- 所以生成的日期是
2001-01-20 18:00:00
如果您使用:
SELECT TO_DATE('2018/01/01', 'RRRR/MM/DD HH24:MI:SS')
FROM DUAL;
然后:
RRRR
匹配2018
.MM
匹配01
.DD
匹配01
.- 所以生成的日期是
2018-01-01 00:00:00
sqlfiddle here
您生成的是两个完全不同的日期,相隔将近 17 年。
In the first case it is returning 679 rows but in second case it is returning 0 rows. 679 correct number of rows we have.
在第一种情况下,您将获得 2001-01-20T18:00:00
.
在第二种情况下,您将获得 2018-01-01T00:00:00
.
鉴于使用的日期分别是 01-JAN-2018
和 2018-01-01
,我认为第二个是正确的,你应该得到 0 行而不是 679 行。