DB2 UDF异常处理

时间:2017-12-14 13:22:07

标签: exception-handling db2 user-defined-functions sql-timestamp

我正在使用DB2中的用户定义函数(UDF)的异常处理。

我的问题的起始位置是,我想在具有特定格式的varchar-timestamps的表上进行SELECT,并将它们转换为timestamp-datatype。

以下SQL语句显示了一个positiv szenario。所有varchar-timestamp都有效。 SELECT将成功:

DROP TABLE TMP_TSP;
CREATE TABLE TMP_TSP (TSP_VARCHAR VARCHAR(100) NOT NULL UNIQUE);
INSERT INTO TMP_TSP VALUES ('2017-02-27');
INSERT INTO TMP_TSP VALUES ('2017-02-28');
SELECT TSP_VARCHAR, timestamp_format(TSP_VARCHAR, 'YYYY-MM-DD') TSP FROM tmp_tsp;

到目前为止一切顺利。但是如果表包含无效的varchar-timestamp,则SELECT-Statement将失败:

DROP TABLE TMP_TSP;
CREATE TABLE TMP_TSP (TSP_VARCHAR VARCHAR(100) NOT NULL UNIQUE);
INSERT INTO TMP_TSP VALUES ('2017-02-27');
INSERT INTO TMP_TSP VALUES ('2017-02-28');
INSERT INTO TMP_TSP VALUES ('2017-02-29'); -- Invalid Date!
select TSP_VARCHAR, timestamp_format(TSP_VARCHAR, 'YYYY-MM-DD') TSP from tmp_tsp;

SELECT-Statement的执行中断了以下errormessage:

  

[错误代码:-20448,SQL状态:22007]“2017-02-29”不能   使用格式字符串“YYYY-MM-DD”解释TIMESTAMP_FORMAT   function .. SQLCODE = -20448,SQLSTATE = 22007

我正在寻找SELECT这些时间戳异常安全的解决方案,这意味着,如果varchar-timestamp有效,它应该被转换为时间戳,如果它是无效的,比如'2017-02-29',应该返回null。 SELECT语句应该具有以下结果:

  

2017-02-27 2017-02-27 00:00:00

     

2017-02-28 2017-02-28 00:00:00

     

2017-02-29 null

我尝试创建一个封装函数 timestamp_format 的UDF,并为异常处理添加一些逻辑,例如:通过DECLARE CONTINUE HANDLER。不幸的是,直到现在我还没有成功。

我正在使用DB2 / LINUXX8664 10.5.7。

可能你可以帮忙吗?!非常感谢提前!

3 个答案:

答案 0 :(得分:0)

我不明白为什么您认为需要使用VARCHARTSP_VARCHARVARCHAR转换为TIMESTAMP_FORMAT,我无法理解告诉你你的UDF有什么问题,因为你选择不发布它的来源或错误,但看起来应该是这样的:

create or replace function to_timestamp_safe (
  str varchar(100),
  fmt varchar(100)
) 
returns timestamp 
deterministic 
no external action contains sql 
begin 
  declare continue handler for sqlstate '22018' -- on conversion error
    return null; 
  return to_timestamp(str, fmt); 
end

然后,您需要在查询中使用它:

select 
  TSP_VARCHAR, 
  timestamp_format(to_timestamp_safe(TSP_VARCHAR, 'YYYY-MM-DD'), 'YYYY-MM-DD') TSP 
from tmp_tsp;

答案 1 :(得分:0)

感谢mustaccio !我的核心问题是我无法执行这个create-function-statement。但现在我找到了一个解决方案:让文件 tmp.sql 包含以下语句

create or replace function to_timestamp_safe (
  str varchar(100),
  fmt varchar(100)
) 
returns timestamp 
deterministic 
no external action contains sql 
begin 
  declare continue handler for sqlstate '22007' -- on conversion error
    return null;
  return to_timestamp(str, fmt);
end
@

然后我可以使用以下命令在DB2 CLP中执行它:

db2 -td@ -vf  tmp.sql

答案 2 :(得分:0)

这是我的解决方案,不需要UDF

SELECT 
 XMLCAST(XMLQUERY('if (. castable as xs:date) then . else ()'
  PASSING '2017-02-29') AS DATE)
FROM SYSIBM.SYSDUMMY1

使用XQUERY测试有效日期,返回传递的值,否则返回一个空元素,该元素将转换为NULL