DB2 UDF 异常处理
Posted
技术标签:
【中文标题】DB2 UDF 异常处理【英文标题】:DB2 UDF Exception Handling 【发布时间】:2017-12-14 13:22:06 【问题描述】:我正在努力处理 DB2 中用户定义函数 (UDF) 的异常处理。
我的问题的出发点是,我想选择具有特定格式的 varchar-timestamps 的表并将它们转换为时间戳数据类型。
以下 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 语句的执行被以下错误消息中断:
[错误代码:-20448,SQL状态:22007]“2017-02-29”不能 使用格式字符串“YYYY-MM-DD”解释 TIMESTAMP_FORMAT 函数.. 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 无效
我尝试创建一个 UDF,它封装了函数 timestamp_format 并添加了一些异常处理逻辑,例如通过声明继续处理程序。不幸的是,直到现在我都没有成功。
我正在使用 DB2/LINUXX8664 10.5.7。
也许你能帮忙?!非常感谢!
【问题讨论】:
【参考方案1】:我不明白您为什么认为需要使用 TIMESTAMP_FORMAT
将 VARCHAR
列 TSP_VARCHAR
转换为 VARCHAR
,而且我无法告诉您 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;
【讨论】:
【参考方案2】:感谢 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
【讨论】:
【参考方案3】:这是我的解决方案,不需要 UDF
SELECT
XMLCAST(XMLQUERY('if (. castable as xs:date) then . else ()'
PASSING '2017-02-29') AS DATE)
FROM SYSIBM.SYSDUMMY1
使用XQUERY
测试有效日期,返回传递的值,否则返回一个空元素,该元素转换为NULL
【讨论】:
以上是关于DB2 UDF 异常处理的主要内容,如果未能解决你的问题,请参考以下文章
关于db2处理特殊字段出现异常java.io.charConversionException