Postgres :时区为时间戳类型输入语法无效:""



我是Postgres数据库的新手。我得到错误:

时区的类型timestamp的无效输入语法:">

当尝试从java运行以下查询时":从_日期"以及":upto_date";在java中执行时将被替换为null。关于如何解决这个问题有什么想法吗?

select tm.*
from team tm
and tm.schedule_finish  >=  (case
when :from_date is null or :upto_date is null  
then TO_CHAR(to_date(concat(TO_CHAR(LOCALTIMESTAMP - INTERVAL '1 month','YYYY-MM') , '-01'),'YYYY-MM-DD'),'YYYY-MM-DD')
when (date_part('year',age(:upto_date,:from_date))*12+date_part('month',age(:upto_date,:from_date)))>36 
then TO_CHAR(to_date(concat(TO_CHAR(LOCALTIMESTAMP -INTERVAL '1 month','YYYY-MM') , '-01'),'YYYY-MM-DD'),'YYYY-MM-DD')
else TO_CHAR(:from_date,'YYYY-MM-DD')
end)::timestamp

我有点不清楚这些参数在传递到查询时的类型。

TO_CHAR(:from_date,'YYYY-MM-DD')表明它是timestamptimestamptz值(例如作为java.time.LocalDatejava.time.OffsetTime传递(

然而,错误消息似乎表明您正在将字符串作为参数传递(这有点危险,因为在这种情况下,调用age()函数时依赖于隐式数据类型转换(。

假设您确实传递了字符串,您可以通过将第一个WHEN部分中的空字符串转换为NULL来处理它们。这样,后续表达式就不必处理空字符串。

我将为age((函数的调用添加一个显式转换。您也不需要调用age()两次,您可以直接将结果与interval常量age(...) > interval '36 month'进行比较。to_date()to_char()之间的来回只是为了获得上个月第一天的时间戳值也是不必要的。

如果then部分中的所有表达式都已返回timestamp,则不再需要将整个CASE表达式强制转换为timestamp

(case
when nullif(trim(:from_date),'') is null or nullif(trim(:upto_date), '') is null  
then date_trunc('month', LOCALTIMESTAMP - INTERVAL '1 month')
when age(to_date(:upto_date, 'yyyy-mm-dd'), to_date(:from_date, 'yyyy-mm-dd')) > interval '36 month'
then date_trunc('month', LOCALTIMESTAMP - INTERVAL '1 month')
else to_timestamp(:from_date,'YYYY-MM-DD')
end)

如果你想用你的";日期串";,你必须首先转换它们:

to_date(:from_date, 'yyyy-mm-dd') - interval '1 month'

最新更新