DB2 / 400 select *有效,但count(*)不起作用

时间:2019-09-26 22:05:54

标签: sql db2 ibm-midrange

在尝试检索保险系统的一些记录时,我遇到了一个奇怪的怪现象。 似乎当我说选择时查询就会运行,但是当我做一个count()时它会发出有关日期格式的抱怨。 有点背景,我们的日期以两种方式之一存储为整数(是的,我知道这很可怕)。 YYMMDD适用于2000年之前的年份,CYYMMDD适用于1999年。

  1. 1999年10月21日变为991021
  2. 2000年10月21日变为1001021。

这是下面的代码,我已经评论了有效的方法,包括了无效的错误。 IBM大约在1980年出现了执行不力的想法。

    -- returns rows correctly
select * from mudata.hdk01
where date(to_date(to_char(A08 + 19000000, '99999999'), 'YYYYMMDD')) < '01/01/1999'
fetch first 100 rows only;

-- refuses with error
-- java.sql.SQLException: [SQL0181] Value in date, time, or timestamp string not valid.
-- Query 1 of 1, Rows read: 0, Elapsed time (seconds) - Total: 0.093, SQL query: 0.093, Reading results: 0
select count(*) from mudata.hdk01
where date(to_date(to_char(A08 + 19000000, '99999999'), 'YYYYMMDD')) < '01/01/1999'
fetch first 100 rows only;

2 个答案:

答案 0 :(得分:4)

创建以下SQL UDF:

CREATE OR REPLACE FUNCTION TO_DATE_SAFE (P_DT INT)
RETURNS DATE
DETERMINISTIC
NO EXTERNAL ACTION
BEGIN
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
    RETURN date(to_date(to_char(P_DT + 19000000, '99999999'), 'YYYYMMDD'));
END

并使用以下语句查找具有违反规则的值的行:

select A08 
from mudata.hdk01
where to_date_safe(A08) is null and A08 is not null

答案 1 :(得分:3)

select count(*)仅返回1行,因此fetch first 100 rows only没有影响。

因此您的第一个查询仅读取100行。

第二个查询正在读取所有行。在随后的几行中,您的A08字段中有错误的数据。

更好的解决方案是拥有一个用户定义函数(UDF),您可以调用该函数来转换日期,这将使您能够处理错误数据……返回NULL或返回一些有效日期。

您可以滚动自己的UDF,也可以使用Alan Campin的开源iDate