我正在使用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。
可能你可以帮忙吗?!非常感谢提前!
答案 0 :(得分:0)
我不明白为什么您认为需要使用VARCHAR
将TSP_VARCHAR
列VARCHAR
转换为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