在尝试检索保险系统的一些记录时,我遇到了一个奇怪的怪现象。 似乎当我说选择时查询就会运行,但是当我做一个count()时它会发出有关日期格式的抱怨。 有点背景,我们的日期以两种方式之一存储为整数(是的,我知道这很可怕)。 YYMMDD适用于2000年之前的年份,CYYMMDD适用于1999年。
这是下面的代码,我已经评论了有效的方法,包括了无效的错误。 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;
答案 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