将一个ISO8601字符串隐式转换为Debezium的TIMESTAMPTZ(postgresql)



我使用的是第三方应用程序(Debezium Connector(。它必须将ISO-8601格式的日期时间字符串写入TIMESTAMPTZ列。不幸的是,这失败了,因为没有从varchar到时间戳tz的隐式转换

我确实注意到以下作品:

SELECT TIMESTAMPTZ('2021-01-05T05:17:46Z');
SELECT TIMESTAMPTZ('2021-01-05T05:17:46.123Z');

我尝试了以下方法:

  1. 创建一个函数和一个强制转换
CREATE OR REPLACE FUNCTION varchar_to_timestamptz(val VARCHAR) 
RETURNS timestamptz AS $$
SELECT TIMESTAMPTZ(val) INTO tstz;
$$ LANGUAGE SQL;
CREATE CAST (varchar as timestamptz) WITH FUNCTION varchar_to_timestamptz (varchar) AS IMPLICIT;

不幸的是,它给出了以下错误:

函数时间戳(字符变化(不存在

  1. 我也尝试了与上面相同的操作,但使用了plpgsql,但得到了相同的错误。

  2. 我试着写一个手动解析,但可选的微秒段出现了问题,这给了我以下

CREATE OR REPLACE FUNCTION varchar_to_timestamptz (val varchar) RETURNS timestamptz AS $$ 
SELECT CASE 
WHEN $1 LIKE '%.%' 
THEN to_timestamp($1, 'YYYY-MM-DD"T"HH24:MI:SS.USZ')::timestamp without time zone at time zone 'Etc/UTC' 
ELSE to_timestamp($1, 'YYYY-MM-DD"T"HH24:MI:SSZ')::timestamp without time zone at time zone 'Etc/UTC' END $$ LANGUAGE SQL;

这很有效,但感觉不正确。

有没有更好的方法来处理这种隐含的演员阵容?

如果值应该在插入时转换,请定义赋值强制转换。你不需要任何功能;使用类型输入和输出功能可以:

CREATE CAST (varchar AS timestamptz) WITH INOUT AS ASSIGNMENT;

请注意,扰乱标准数据类型的强制转换可能会导致问题,因为这会增加歧义。如果你能找到一种使用显式演员阵容的方法,那会更好。

最新更新