ORA-01847 - 添加不相关的AND子句时出错

时间:2017-07-25 09:45:45

标签: sql oracle date

我正在尝试进行一个非常简单的查询,因为我一直在犯这个错误,所以我很生气:

  

ora-01847一个月中的某一天必须在1月到最后一天之间

这是查询

select *
  from TAB1 H 
  JOIN TAB2 D ON D.PAR2 = H.PAR1
  where TO_DATE(D.DATE, 'dd-mm-yyyy') <> sysdate
  and  H.FIELD = 'TEST';

奇怪的是,如果我将两个AND条款中的任何一个带走,它将无法工作。如果我不是使用最后一个AND子句来检索某些记录,而是直接传递他们的id,所以我认为这不是日期格式或其他任何问题。

D.DATE和H.FIELD都定义为VARCHAR2(255 CHAR)

任何抬头?

编辑: [导致问题的实际日期]

01/10/2017
01/10/2018
01/10/2018
01/10/2017
01/05/2023
01/05/2023
01/05/2023
01/05/2023
01/05/2023
01/10/2017
01/05/2018
01/02/2018

!!!&GT;向下滚动以获取此样本时,它再次给了我这个错误。我只能猜测它发生在列

中的'TEST'值到达的行中

编辑:

 select H.*
      from TAB1 H 
      JOIN TAB2 D ON D.PAR2 = H.PAR1
      where TO_DATE(D.DATE, 'dd-mm-yyyy') <> sysdate;

会出现同样的错误。消除where子句或选择所有内容将“解决”问题。

编辑:

select ID as ID, null as ID_REF
    from TAB1
    where FIELD = 'TEST'
  union all
  select NULL as ID, ID_REF as ID_REF
  from TAB2
  where TO_DATE(DATE, 'dd-mm-yyyy') <> sysdate;

这样,向下滚动(据称在两个条件下达到记录)会产生同样的错误。

1 个答案:

答案 0 :(得分:4)

ORA-01847的消息是

  

每月的某一天必须在1月到最后一天之间

所以明显的候选人是

> where TO_DATE(D.DATE, 'dd-mm-yyyy') <> sysdate

也就是说,D.DATE中包含的值包含无法转换为日期的字符串,例如'32-05-2017'。当我们使用VARCHAR列来保存日期或数字时,这始终是一种风险。

  

&#34;我滚动浏览结果集,只要它加载了第100个结果,就会打击&#34;

是的,这就是我提出的关于抓取的问题。显然,您在d.date列中有duff数据(非日期):在h.field上过滤只会将duff更快地拖到结果集的顶部,而不是滚动整个表格。

您可以使用以下函数调查腐烂的比例:

create or replace function is_date
      (p_date_str in varchar2
        , p_date_fmt in varchar2 := 'dd-mm-yyyy' )
     return varchar2
as
    return_value varchar2(20);
    l_date date; 
begin
    begin
        l_date := to_date(p_date_str, p_dae_fmt);
        return_value := 'DATE';
    exception
        when others then
            return_value := 'NOT A DATE';
    end;
    return return_value;
end; 
/

此查询将返回您需要思考的记录:

select d.id -- or whatever
        , d.date
from tab2 d
where is_date(d.date) = 'NOT A DATE'
/

您接下来要做的事情取决于您发现的行李的性质和数量。这个问题可能值得一个新问题。