我明白
"ORA-01841: (full) year must be between -4713 and +9999, and not be 0."
基于随机日历数据。
我运行以下查询:
insert into TEMP_TBL
SELECT COUNT(ea.employee_rk) AS no_logins,
ea.country_cd,
ea.nsb_department,
ea.employee_id,
NULL,
NULL
FROM EMPLOYEE_ACTIVITY ea
JOIN employee_activity_ded ead
ON ead.employee_act_ver_sk=ea.employee_act_ver_sk
JOIN employee_start_end ese
ON ese.employee_id = ea.employee_sk
AND ea.ACTIVITY_DT>=ese.START_REV
AND ea.ACTIVITY_DT <ese.end_rev
WHERE TRUNC(ea.ACTIVITY_DT) BETWEEN to_date('01-AUG-2017','DD-MON-YYYY HH24:MI:SS') AND to_date('31-AUG-2017','DD-MON-YYYY HH24:MI:SS');
DESC TEMP_TBL;
VALUE_SEC NUMBER
COUNTRY_CD VARCHAR2(50 BYTE)
NSB_DEPARTMENT VARCHAR2(50 BYTE)
EMPLOYEE_RK VARCHAR2(32 BYTE)
ACCESS_DAY DATE
ACCESS_TIME DATE
DESC employee_start_end;
EMPLOYEE_VERSION_SK NUMBER(20,0)
EMPLOYEE_SK NUMBER(20,0)
START_REV DATE
END_REV DATE
EMPLOYEE_ID VARCHAR2(32 BYTE)
EMPLOYEE_ACTIVITY
有大量列,但重要的是:
ea.ACTIVITY_DT DATE
此错误发生在表中的随机数据上。奇怪的是,当我将 TO_DATE
添加到 ese.START_REV
和 ese.END_REV
时,错误不再出现。
ese.START_REV
和 to ese.END_REV
均采用 DATE
作为数据类型。
添加TO_DATE
后,相同的查询运行没有错误:
insert into TEMP_TBL
SELECT COUNT(ea.employee_rk) AS no_logins,
ea.country_cd,
ea.nsb_department,
ea.employee_id,
NULL,
NULL
FROM EMPLOYEE_ACTIVITY ea
JOIN employee_activity_ded ead
ON ead.employee_act_ver_sk=ea.employee_act_ver_sk
JOIN employee_start_end ese
ON ese.employee_id = ea.employee_sk
AND ea.ACTIVITY_DT>=to_date(ese.START_REV)
AND ea.ACTIVITY_DT <to_date(ese.end_rev)
WHERE TRUNC(ea.ACTIVITY_DT) BETWEEN to_date('01-AUG-2017','DD-MON-YYYY HH24:MI:SS') AND to_date('31-AUG-2017','DD-MON-YYYY HH24:MI:SS');
最佳答案
[TL;DR] 鉴于您指定的数据类型,添加 TO_DATE
应该没有什么区别,并且您的原始查询应该有效。检查您所描述的表是否具有正确的所有者(并且您没有描述属于不同所有者的类似名称的表)并且是否具有您指定的数据类型,因为如果其中一个是字符串,则问题将有意义(但不如果它们都是日期就没有意义)。
What is strange is that when I add to_date to
ese.START_REV
and toese.START_REV
the error doesn't appear anymore.
这意味着查询以某种方式使用字符串比较语义来比较列,并将日期隐式转换为字符串,但由于您声明了 ea.ACTIVITY_DT,所以没有明显的列会导致这种情况发生>、ese.START_REV
和 ese.END_REV
都是 DATE
数据类型,应该仅使用日期比较语义而不是字符串比较语义进行比较.
查看修改后的查询:
JOIN employee_start_end ese
ON ese.employee_id = ea.employee_sk
AND ea.ACTIVITY_DT>=to_date(ese.START_REV)
AND ea.ACTIVITY_DT <to_date(ese.end_rev)
鉴于您声明 ese.START_REV
和 ese.end_rev
属于 DATE
数据类型,这实际上是:
JOIN employee_start_end ese
ON ese.employee_id = ea.employee_sk
AND ea.ACTIVITY_DT >= TO_DATE(
TO_CHAR(
ese.START_REV,
NLS_DATE_FORMAT
),
NLS_DATE_FORMAT
)
AND ea.ACTIVITY_DT < TO_DATE(
TO_CHAR(
ese.end_rev,
NLS_DATE_FORMAT
),
NLS_DATE_FORMAT
)
其中NLS_DATE_FORMAT
由以下方式给出:
SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT'
当您在两次转换中使用相同的格式模型从日期转换为字符串并返回日期时,这应该对查询产生零差异。
I get the
ORA-01841: (full) year must be between -4713 and +9999, and not be 0.
这可能是从字符串值到日期的隐式转换,其中 NLS_DATE_FORMAT
与字符串值的格式不匹配 - 同样,它只对您的列之一有意义一个字符串而不是日期。
如果您显示列的顺序与预期顺序不匹配,则另一个可能出现问题的地方是 INSERT
语句中。尝试将列名称添加到 INSERT
中:
INSERT INTO TEMP_TBL(
VALUE_SEC,
COUNTRY_CD,
NSB_DEPARTMENT,
EMPLOYEE_RK,
ACCESS_DAY,
ACCESS_TIME,
)
SELECT COUNT(ea.employee_rk) AS no_logins,
ea.country_cd,
ea.nsb_department,
ea.employee_id,
NULL,
NULL
FROM ...
关于sql - ORA-01841 : (full) year must be between -4713 and +9999, 且不为 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46584574/