【问题标题】:ORA-01847 day of month must be between 1 and last day of month error when taking the sum or countORA-01847 取总和或计数时,月份的日期必须介于 1 和月份的最后一天之间
【发布时间】:2018-02-08 10:22:39
【问题描述】:

在我的数据库中,当我尝试运行以下查询时,我有一个 varchar2 格式的日期列,我收到 ORA - 01847 错误。

SELECT NVL(SUM(TOTAL_QOH),0) 
 FROM V_STOCK_ENQUIRY 
 WHERE LOCATION_ID = 82 
   AND TO_DATE(EXPIRY_DATE, 'DD-MM-YYYY')>= TO_DATE('01-11-2017', 'DD-MM-YYYY') 
   AND TO_DATE(EXPIRY_DATE, 'DD-MM-YYYY')<= TO_DATE('01-11-2017', 'DD-MM-YYYY') 

但是当我尝试运行相同的查询但只取 TOTAL_QOH 而不是总和时,我得到了正确的结果。谁能帮我解决这个问题。

【问题讨论】:

  • 不应该是select sum(nvl(TOTAL_QOH, 0))吗?
  • 这与mysqlsql-server 有什么关系?` 了解您的 DBMS.. 选择正确的!
  • @Abra 至少在理论上,在最后应用一次nvl() 比对每一行执行并添加所有零更有效。
  • 我的猜测是您的数据中某处的值无效,并且您的 IDE(PL/SQL Developer 等)在第一个屏幕后暂停,因此除非您应用聚合函数,否则不会出现错误要求数据库处理所有值。
  • 如果是这样,那么当我尝试直接获取该列时它是如何工作的? 通常,像 PL/SQL Developer、SQL Developer、TOAD 等 IDE 不会显示查询中的所有行,而是在第一个屏幕或一些可配置的行数之后暂停。如果您的无效值在第 20000 行,除非您明确地获取至少 20000 行,否则您不会命中它,因为 SQL Developer 或您使用的任何东西在 100 行后暂停。

标签: oracle date datetime


【解决方案1】:

获取部分行可能不会导致错误,但是当您求和时,会检查每一行并发生错误。检查您的数据,某处应该有错误的值,例如,您可以使用下面的块代码。但最好的选择是将列类型更改为date。将日期存储为 varchars 会导致这样的问题,并且更难构建查询等。

declare 
  dt date;
begin 
  for r in (select rowid, expiry_date from v_stock_enquiry) loop
    begin
      dt := to_date(r.expiry_date, 'dd-mm-yyyy');
    exception when others then
      if sqlcode in (-1839, -1847) then
        dbms_output.put_line('value: '||r.expiry_date||' is not correct');
        dbms_output.put_line('rowid: '||r.rowid);
        dbms_output.put_line(sqlerrm);
      else
        dbms_output.put_line(sqlcode);
        dbms_output.put_line(sqlerrm);
      end if;
    end;
  end loop;
end;

【讨论】:

  • 数据中没有错误的值,我很确定。
猜你喜欢
  • 2017-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-21
  • 1970-01-01
相关资源
最近更新 更多