DB2 select ... insert无法将a日转换为日期

时间:2019-03-29 21:44:58

标签: sql db2-400

我正在尝试执行选择插入,该插入使用日期(DOB)的DECIMAL(8,0)表示形式,将其转换为日期,然后将其插入另一个表中。

INSERT INTO myschema.beneficiary_info  
    (name, address, city, state, zip, dob, spouse) 
SELECT 
    jh.bname, jh.badd1, jh.bcity, jh.bstate, jh.bzip,
    CASE 
        WHEN JH.BDOB8 != '0' AND JH.BDOB8 IS NOT NULL THEN 
            DATE(
                TIMESTAMP_FORMAT(
                    CHAR(jh.bdob8) ,'YYYYMMDD'))
        ELSE null
    END,
    --jh.bdob8,
    jh.bspous
FROM TABLE(MYSCHEMA.REMOTE_TABLE()) JH    -- function pointing to a remote database

但是,其中大约有5,000条记录(具有成功处理的日期和空值),失败并显示

[Code: -181, SQL State: 22007] [SQL0181] Value in date, time, or timestamp string not valid.

我将数据缩小到有问题的行,并发现了这一点(显示了case语句的结果和实际的bdob8字段:

0006        bdob8     
1958-12-24  19581224  
(null)      19620229   
1965-02-07  19650207   

ap日似乎导致select ... insert失败。

这时,只需将null传递给插入,case语句就已经成功地导航了null。但是由于某种原因,当日期/时间戳记功能为barf并返回null时,整个过程就会中断。

正在寻找如何克服明显无法应付leap日的想法...

(使用IBMi DB2 V7R3M0 L00)

2 个答案:

答案 0 :(得分:1)

正如戈登指出的那样,1962年不是a年。

我建议您构建自己的用户定义函数(UDF),以进行日期转换...

这样,您将可以控制无效日期返回的内容。您还可以处理常见的数字特殊值(或返回null)

例如

  • 00000000-> 0001-01-01
  • 99999999-> 9999-12-31

有一个流行的UDF开源软件包iDate by Alan Campin,它将为您自己的UDF奠定一个良好的起点。

答案 1 :(得分:0)

使用UDF过滤错误数据

ALTER USER postgres PASSWORD 'postgres'

它是这样访问的:

CREATE FUNCTION ASDATE (
  INPUTDATESTR VARCHAR(10) )
  RETURNS DATE
  LANGUAGE SQL
  SPECIFIC ASDATE
  NOT DETERMINISTIC
  MODIFIES SQL DATA
  CALLED ON NULL INPUT
  CONCURRENT ACCESS RESOLUTION DEFAULT
  SET OPTION  ALWBLK = *ALLREAD ,
  ALWCPYDTA = *OPTIMIZE ,
  COMMIT = *NONE ,
  DECRESULT = (31, 31, 00) ,
  DYNDFTCOL = *NO ,
  DYNUSRPRF = *USER ,
  SRTSEQ = *HEX
  BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN NULL ;
RETURN DATE ( TIMESTAMP_FORMAT ( CHAR ( INPUTDATESTR ) , 'YYYYMMDD' ) ) ;
END  ;

非常感谢Charles向我指出了正确的方向,并且https://stackoverflow.com/a/39683452/2129574

UDF中的选项是 IBM Navigator for i 填写的缺省值;欢迎对功能改进发表任何评论。