首页 > 解决方案 > DB2/400 select * 有效,但 count(*) 无效

问题描述

在尝试检索保险系统的一些记录时,我遇到了一个奇怪的问题。似乎当我说 select 时查询会运行,但是当我执行 count( )时它会抱怨日期格式。一点背景知识,我们的日期以两种方式之一存储为整数(是的,我知道这很可怕)。YYMMDD 表示 2000 年之前的年份,CYYMMDD 表示 1999 年之前的年份。

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

这是下面的代码,我已经评论了有效的方法以及无效时包含的错误。大约 1980 年的 IBM 是一个执行不力的想法的集合体。

    -- 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;

标签: sqldb2ibm-midrange

解决方案


创建以下 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

推荐阅读