简体   繁体   English

如何不对 PostgreSQL CASE 表达式的 ELSE 部分求值

[英]How to not evaluate the ELSE part of a PostgreSQL CASE expression

I have to convert two types of input to a valid timestamp:我必须将两种类型的输入转换为有效的时间戳:

  1. '1626273917256' '1626273917256'
  2. '2021-07-14 16:45:17+02' '2021-07-14 16:45:17+02'

Right now I'm doing it like this:现在我是这样做的:

timestamp_comumn = CASE WHEN ? ~ '\d{13}' THEN to_timestamp(?::bigint/1000) ELSE ?::timestamp END

For the case when the input is '1626273917256', this results in:对于输入为“1626273917256”的情况,结果为:

timestamp_comumn = CASE WHEN '1626273917256' ~ '\d{13}' THEN to_timestamp('1626273917256'::bigint/1000) ELSE '1626273917256'::timestamp END

But this throws an error:但这会引发错误:

SELECT CASE WHEN '1626273917256' ~ '\d{13}' THEN to_timestamp('1626273917256'::bigint/1000) ELSE '1626273917256'::timestamp END
ERROR:  date/time field value out of range: "1626273917256"
LINE 1: ...N to_timestamp('1626273917256'::bigint/1000) ELSE '162627391...
                                                             ^
HINT:  Perhaps you need a different "datestyle" setting.

clearly because PostgreSQL evaluates the ELSE part as well.很明显,因为 PostgreSQL 也会评估 ELSE 部分。

Is there a way to do this in SQL?有没有办法在 SQL 中做到这一点? Or the only option is to do this in the scripting part?或者唯一的选择是在脚本部分执行此操作?

Your tests are deceiving you as to how this will work in production.您的测试正在欺骗您这将如何在生产中工作。

PostgreSQL can see that '1626273917256'::timestamp is a constant and tries to evaluate it ahead of time. PostgreSQL 可以看到'1626273917256'::timestamp是一个常量,并尝试提前评估它。 As long as you are referencing something other than a literal you should be fine.只要你引用的不是文字,你应该没问题。

=> WITH str_times (t) AS (VALUES ('1626273917256'::text)) SELECT CASE WHEN t ~ '\d{13}' THEN to_timestamp(t::bigint/1000) ELSE t::timestamp END FROM str_times;
           t            
────────────────────────
 2021-07-14 14:45:17+00
(1 row)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM