我有一张表,该表根据“日期”列类型计算一些度量。 同样,应该将日期存储为波斯日历,但是最后当我使用TO_DATE函数更改其类型时,在5月的19、20、21天出现了ORA-01861错误,而该日期已经存在,第二个波斯日历的一个月有31天。 这是我的查询:
with a as
(select to_char(to_date('20190518', 'YYYYMMDD'),
'YYYYMMDD',
'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
from DUAL
UNION ALL
select to_char(to_date('20190519', 'YYYYMMDD'),
'YYYYMMDD',
'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
from DUAL
UNION ALL
select to_char(to_date('20190520', 'YYYYMMDD'),
'YYYYMMDD',
'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
from DUAL
UNION ALL
select to_char(to_date('20190521', 'YYYYMMDD'),
'YYYYMMDD',
'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
from DUAL
UNION ALL
select to_char(to_date('20190522', 'YYYYMMDD'),
'YYYYMMDD',
'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
from DUAL)
SELECT TO_DATE(PERSIAN_DATE, 'YYYY/MM/DD') pers_date FROM A
我的oracle数据库版本是Oracle 12.2.0.1.0
答案 0 :(得分:1)
将字符串转换为DATE,然后转换为字符串,然后再次转换为DATE,这是没有用的。
尝试这个:
WITH a AS
(SELECT TO_DATE('20190518', 'YYYYMMDD') PERSIAN_DATE
FROM DUAL
UNION ALL
SELECT TO_DATE('20190519', 'YYYYMMDD') PERSIAN_DATE
FROM DUAL
UNION ALL
SELECT TO_DATE('20190520', 'YYYYMMDD') PERSIAN_DATE
FROM DUAL
UNION ALL
SELECT TO_DATE('20190521', 'YYYYMMDD') PERSIAN_DATE
FROM DUAL
UNION ALL
SELECT TO_DATE('20190522', 'YYYYMMDD') PERSIAN_DATE
FROM DUAL)
SELECT to_char(PERSIAN_DATE, 'YYYYMMDD', 'NLS_CALENDAR=PERSIAN') pers_date
FROM A
或更短:
SELECT TO_CHAR(TO_DATE('20190517', 'YYYYMMDD')+LEVEL, 'YYYYMMDD', 'NLS_CALENDAR=PERSIAN') pers_date
FROM dual
CONNECT BY LEVEL <= 5;
或使用DATE
文字和NLS会话值:
ALTER SESSION SET NLS_CALENDAR = 'PERSIAN';
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYYMMDD';
SELECT DATE '2019-05-17' + LEVEL pers_date
FROM dual
CONNECT BY LEVEL <= 5;
答案 1 :(得分:0)
当您仅对第18个(没有问题)执行选择并添加原始值时,您将看到它返回
with a as
(select to_char(to_date('20190518', 'YYYYMMDD'),
'YYYYMMDD',
'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
from DUAL)
SELECT PERSIAN_DATE, TO_DATE(PERSIAN_DATE, 'YYYY/MM/DD') pers_date FROM A;
Persian Date pers_date
13980228 28/FEB/98 00:00:00
因此oracle正在尝试舍弃前两个字符,并确定其余日期的最佳日期(确信这不是正确的波斯日期)。
因此,当您在第19次运行时遵循相同的逻辑(我们只能获取到日期的原始值将出错)
with a as
(select to_char(to_date('20190519', 'YYYYMMDD'),
'YYYYMMDD',
'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
from DUAL)
SELECT PERSIAN_DATE pers_date FROM A;
Persian Date
13980229
按照与上述相同的逻辑,丢弃前两个字符,您得到1998年2月29日……这不是一个有效的日期。
正如其他人在评论中所述,Oracle只是存储它不关心日历的日期,因此您需要转换为适当的日历以进行显示。
有关oracle如何存储日期的详细说明,请参见