Snowflake是否有TRY_CONVERT_TIMEZONE函数?或容错时区转换方案
Snowflake 带容错机制的GMT转账户时区实现
问题背景
现有三张业务表:
交易表(Txn table)
| txn_id | txn_date | acc_id |
|---|---|---|
| T1 | 2022-04-01 00:02:04 | A1 |
| T2 | 2022-04-02 00:07:03 | A2 |
| T3 | 2022-04-03 00:08:04 | A3 |
| T4 | 2022-04-04 00:09:05 | A4 |
| T5 | 2022-04-05 00:12:06 | A5 |
账户表(Acc table)
| acc_id | tz_id |
|---|---|
| A1 | TZ2 |
| A2 | TZ4 |
| A3 | TZ6 |
| A4 | TZ8 |
| A5 | TZ10 |
时区表(Timezone table)
| tz_id | tz_desc | tz_cd | tz_long_name |
|---|---|---|---|
| TZ2 | US/Hawaii | HST | North America Hawaii |
| TZ4 | Australia/Sydney | AEST | Australian Eastern |
| TZ6 | BLABLABLA******* | XXX | System Generated |
| TZ8 | #$#$%%@% | XXX | System Generated |
| TZ10 | <> | XXX | System Generated |
核心约束
txn_date字段存储的是GMT时间- 时区表中存在无效时区值,直接使用原生
convert_timezone函数会抛出异常
需要实现类似TRY_CAST的容错转换逻辑:将GMT时间转为对应账户的时区,转换失败时返回NULL,最终输出格式如下:
| txn_id | txn_date | acc_id | tz_id | tz_desc | local_txn_date |
|---|---|---|---|---|---|
| T1 | 2022-04-01 00:02:04 | A1 | TZ2 | US/Hawaii | 转换后的时间戳 |
| T2 | 2022-04-02 00:07:03 | A2 | TZ4 | Australia/Sydney | 转换后的时间戳 |
| T3 | 2022-04-03 00:08:04 | A3 | TZ6 | BLABLABLA******* | NULL |
| T4 | 2022-04-04 00:09:05 | A4 | TZ8 | #$#$%%@% | NULL |
| T5 | 2022-04-05 00:12:06 | A5 | TZ10 | <> | NULL |
解决方案
1. 创建带容错的自定义时区转换函数
通过SQL UDF封装原生convert_timezone,利用TRY函数捕获转换错误:
CREATE OR REPLACE FUNCTION TRY_CONVERT_TIMEZONE( source_tz STRING, target_tz STRING, input_timestamp TIMESTAMP_NTZ ) RETURNS TIMESTAMP_TZ LANGUAGE SQL AS $$ TRY(convert_timezone(source_tz, target_tz, input_timestamp)) $$;
2. 关联表查询获取最终结果
调用自定义函数关联三张表,实现转换逻辑:
SELECT t.txn_id, t.txn_date, t.acc_id, a.tz_id, z.tz_desc, TRY_CONVERT_TIMEZONE('GMT', z.tz_desc, t.txn_date) AS local_txn_date FROM Txn t JOIN Acc a ON t.acc_id = a.acc_id JOIN Timezone z ON a.tz_id = z.tz_id;
逻辑说明
- 自定义函数
TRY_CONVERT_TIMEZONE通过TRY关键字包裹原生转换逻辑,当目标时区无效时自动捕获异常并返回NULL - 查询时传入GMT作为源时区、时区表的
tz_desc作为目标时区、交易表的txn_date作为输入时间戳,自动适配有效/无效时区场景
内容的提问来源于stack exchange,提问作者Ajay Ganapathy
相关产品推荐
相关产品推荐

