找出导致Oracle错误的数据

时间:2016-08-09 15:31:55

标签: sql oracle plsql oracle11g

我试图在SQL Developer中运行select语句,将20160809这样的字段强制转换为date。我的查询如下:

select
  to_date(sale_date, 'YYYYMMDD') as sale_date
from properties

这是一个ORA-01839: date not valid for month specified。我已经尝试了从子串到正则表达式的所有内容,试图推断导致错误的值,但没有骰子。有没有办法执行此查询并获取to_date导致其失败的输入?

3 个答案:

答案 0 :(得分:3)

设定:

create table properties(sale_date varchar2(8));
insert into properties values ('20160228');
insert into properties values ('20160230'); 
insert into properties values ('xxxx');

如果你的桌子不是太大,你可以试试这个:

SQL> declare
  2      d date;
  3  begin
  4      for i in (select * from properties) loop
  5          begin
  6              d:= to_date(i.sale_date, 'yyyymmdd');
  7          exception
  8              when others then
  9                  dbms_output.put_line('KO: "' || i.sale_date || '"');
 10          end;
 11      end loop;
 12  end;
 13  /
KO: "20160230"
KO: "xxxx"

PL/SQL procedure successfully completed.

答案 1 :(得分:2)

我认为你可能需要一种暴力方法:

select sale_date
from properties 
where substr(sale_date, 5, 4) not between '0101' and '0131' and
      substr(sale_date, 5, 4) not between '0201' and '0228' and
      substr(sale_date, 5, 4) not between '0301' and '0431' and
      substr(sale_date, 5, 4) not between '0401' and '0430' and
      substr(sale_date, 5, 4) not between '0501' and '0531' and
      substr(sale_date, 5, 4) not between '0601' and '0630' and
      substr(sale_date, 5, 4) not between '0701' and '0731' and
      substr(sale_date, 5, 4) not between '0801' and '0831' and
      substr(sale_date, 5, 4) not between '0901' and '0930' and
      substr(sale_date, 5, 4) not between '1001' and '1031' and
      substr(sale_date, 5, 4) not between '1101' and '1130' and
      substr(sale_date, 5, 4) not between '1201' and '1231';

这并非100%完美。它留下了闰年错误的可能性。您可以使用以下方法手动调查这些:

select sale_date
from properties 
where sales_date like '%0229';

答案 2 :(得分:2)

您使用的是Oracle 12c吗?如果是,那么

with function safe_to_date(p_string VARCHAR2, p_format VARCHAR2) RETURN DATE IS
BEGIN 
  return to_date(p_string, p_format);
EXCEPTION
  WHEN others THEN
    return NULL;
END;
select sale_date from properties
where sale_date is not null and safe_to_date(sale_date,'YYYYMMDD') IS NULL ;

如果您不在Oracle 12c上,可以将safe_to_date放入一个包中,比如" my_pkg"然后这个:

select sale_date from properties
where sale_date is not null and my_pkg.safe_to_date(sale_date ,'YYYYMMDD') IS NULL ;