ORA-01841 :(完整)年份必须介于-4713和+9999之间,而不是0

时间:2017-10-05 11:32:50

标签: sql oracle

我得到了

  

" ORA-01841 :(完整)年份必须介于-4713和+9999之间,而不是   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_REVese.END_REV时,错误不再出现。

ese.START_REVese.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');

3 个答案:

答案 0 :(得分:4)

[TL; DR] 根据您声明的数据类型,添加TO_DATE应该没有区别,您的原始查询应该有效。检查您描述的表是否具有正确的所有者(并且您没有描述属于不同所有者的类似命名的表)并且具有您声明的数据类型,因为如果其中一个是字符串,则问题会有意义(但是如果他们都是约会,就没有意义。)

  

奇怪的是,当我将to_date添加到ese.START_REVese.START_REV时,错误不再出现。

这意味着查询在某种程度上使用字符串比较语义来比较列,并且隐式地将日期转换为字符串,但是由于您声明ea.ACTIVITY_DT,{{1 }和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'

这可能是从字符串值到ORA-01841: (full) year must be between -4713 and +9999, and not be 0.与字符串值的格式不匹配的日期的隐式转换 - 再次,它只是意味着你的一个列是一个字符串和不是约会。

如果您提交列的订单与预期订单不符,则可能在NLS_DATE_FORMAT语句中出现问题的另一个地方。尝试将列名添加到INSERT

INSERT

答案 1 :(得分:0)

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');

您的输入日期格式'01 -AUG-2017'与指定的格式'DD-MON-YYYY HH24:MI:SS'不匹配。

答案 2 :(得分:-1)

我的用户程序,运行正常。

and AUTH_DT between to_date(to_char(to_date(pv_ngaybc),'YYYY-MM-DD') ||' ' || pv_from ,'YYYY-MM-DD HH24:MI:SS')
            and to_date(to_char(to_date(pv_ngaybc),'YYYY-MM-DD') ||' ' || pv_to,'YYYY-MM-DD HH24:MI:SS')