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

Posted

技术标签:

【中文标题】将 ISO8601 字符串隐式转换为 Debezium 的 TIMESTAMPTZ (postgresql)【英文标题】:Implicitly cast an ISO8601 string to TIMESTAMPTZ (postgresql) for Debezium 【发布时间】:2021-06-18 17:35:40 【问题描述】:

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

我确实注意到以下工作:

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

我尝试了以下方法:

    创建一个函数和一个演员表
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;

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

函数 timestamptz(字符变化)不存在

    我也尝试了与上面相同的方法,但使用 plpgsql 并得到了相同的错误。

    我尝试编写手动解析,但可选的微秒段出现问题,这给了我以下信息

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;

哪个有效,但感觉不正确。

有没有更好的方法来处理这种隐式转换?

【问题讨论】:

【参考方案1】:

如果值应该在插入时进行转换,请定义一个赋值转换。你不需要任何功能;使用 type 输入和输出函数就可以了:

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

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

【讨论】:

以上是关于将 ISO8601 字符串隐式转换为 Debezium 的 TIMESTAMPTZ (postgresql)的主要内容,如果未能解决你的问题,请参考以下文章

Python - 将日期的字符串表示形式转换为 ISO 8601

将 ISO8601 字符串转换为自纪元以来的毫秒数

如何将 Excel 中的日期转换为 ISO 8601 格式

将 ISO 8601 日期时间字符串转换为 **Date** 对象时,如何将日期时间重新定位到当前时区?

将日期对象转换为ISO 8601格式的字符串

在Java中将ISO 8601时间戳字符串转换为纪元秒[重复]