首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Oracle日期错误- ORA-01841

Oracle日期错误- ORA-01841
EN

Stack Overflow用户
提问于 2015-03-03 10:48:19
回答 2查看 2.6K关注 0票数 2

我在Oracle11g中有下表。

代码语言:javascript
复制
SQL> DESC tmp_test;
Name                 Type          Nullable Default Comments 
-------------------- ------------- -------- ------- -------- 
SERNO                NUMBER(10)                              
CARDNO               VARCHAR2(25)  Y                         
COL_A                VARCHAR2(255) Y                         
DATEA                DATE          Y                         
DATEB                DATE          Y                         
TAG                  VARCHAR2(255) Y                         
FEEDBACK             CHAR(1)       Y


SQL> 
SQL> SELECT * FROM (SELECT T.COL_A FROM TEMP_TEST T ORDER BY DBMS_RANDOM.VALUE) WHERE ROWNUM <=10;
COL_A
--------------------------------------------------------------------------------
00 OK.20150301-0000
00 OK.20150301-0000
00 OK.20150301-0000
00 OK.20150205-0000
00 OK.20150301-0000
00 OK.20150301-0000
00 OK.20150213-0000
00 OK.20150301-0000
00 OK.20150129-0000
00 OK.20150301-0000
10 rows selected

SQL>

我试图标识表TEMP_TEST中的所有行,其中COL_A中的日期小于SYSDATE-7。

代码语言:javascript
复制
SQL>
SQL> SELECT * FROM TEMP_TEST T WHERE
TO_DATE(SUBSTR(TRIM(T.COL_A),7,8),'YYYYMMDD') < sysdate-7;
**ORA-01841: (full) year must be between -4713 and +9999, and not be 0**
SQL>

该表只包含200行,因此我已经在视觉上检查了数据中的任何问题。所有日期都是有效的。造成此错误的原因可能是什么?

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-03 11:16:26

显然,所有的日期都是无效的,因此出现了错误。我会尝试下面这样的方法(未经测试,但认为没关系),只是为了识别问题记录。

代码语言:javascript
复制
declare 
  v_date date;
begin
  for c in (select col_a from temp_test) loop
    begin
      v_date := to_date(substr(trim(c.col_a),7,8),'YYYYMMDD');
    exception when others then
      dbms_output.put_line(c.col_a);
    end;
  end loop;
end;

请注意,使用others作为唯一的异常处理程序通常被认为是糟糕的做法。在生产代码中,异常应该单独处理。即使当用于调试时,输出SQL错误也更好,但对于第一次只需要几个错误的情况,有时只是懒散就可以了。

票数 2
EN

Stack Overflow用户

发布于 2015-03-03 11:20:55

使用显式游标来调试编号或日期转换错误通常会很快显示出违规的行(在这里,我伪造了TEMP_TEST表):

代码语言:javascript
复制
declare
  cursor l_cur is
    with temp_test(col_a) as (
      select '20150201_abc' col_a from dual union all
      select 'x0150201_abc' col_a from dual union all
      select '20150201_abc' col_a from dual)      
    SELECT * FROM TEMP_TEST T;

  l_data l_cur%rowtype;
  dummy  date;
begin
  open l_cur;
  loop
    fetch l_cur
      into l_data;
    exit when l_cur%notfound;
    begin
      dummy := TO_DATE(SUBSTR(TRIM(l_data.COL_A), 1, 8), 'YYYYMMDD');
    exception
      when others then
        dbms_output.put_line(sqlerrm || ' for ' || l_data.col_a);
    end;
  end loop;
end;

编辑:WHEN OTHERS仅用于交互式调试--请不要在生产代码中使用它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28829844

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档