0

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

我的问题的起始位置是,我想在具有特定格式的 varchar-timestamps 的表上进行 SELECT 并将它们转换为时间戳数据类型。

以下 SQL 语句显示了一个积极的情况。所有 varchar-timestamps 都是有效的。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 的执行被以下错误消息中断:

[错误代码:-20448,SQL 状态:22007] 无法使用 TIMESTAMP_FORMAT 函数的格式字符串“YYYY-MM-DD”解释“2017-02-29”。SQLCODE=-20448,SQLSTATE=22007

我正在寻找一种解决方案来选择那些时间戳异常安全,这意味着,如果 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 空

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

我正在使用 DB2/LINUXX8664 10.5.7。

可能是你可以帮忙吗?!提前谢谢了!

4

3 回答 3

0

我不明白您为什么认为需要将VARCHAR列转换TSP_VARCHARVARCHARusing 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;
于 2017-12-14T14:19:04.947 回答
0

感谢mustaccio!我的核心问题是我无法执行这个创建函数语句。但是现在我找到了一个解决方案:让文件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
于 2017-12-14T15:50:57.720 回答
0

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

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

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

于 2019-11-25T19:40:31.940 回答