You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL查询传入Timestamp参数报date_part函数不唯一错误

问题描述

在PostgreSQL查询中使用java.sql.Timestamp类型变量作为传参执行SQL时,触发如下报错:

bad SQL grammar [select extract(year from LOCALTIMESTAMP) -extract(year from ?)]; nested exception is org.postgresql.util.PSQLException: ERROR: function pg_catalog.date_part(unknown, unknown) is not unique

对应实现代码如下,两种传参写法(直接传入dt对象、显式指定Types.TIMESTAMP类型传参)均无法正常执行,都会触发上述报错:

private void myFN(Timestamp dt) {
        rowSet = jdbcTemplate.queryForRowSet("select extract(year from LOCALTIMESTAMP) -extract(year from ?)", dt);
        rowSet = jdbcTemplate.queryForRowSet("select extract(year from LOCALTIMESTAMP) -extract(year from ?)",
                new Object[] { dt }, new int[] { Types.TIMESTAMP });
    }
报错根因

extract(field from source)是PostgreSQL对date_part(field, source)函数封装的语法糖。预编译SQL执行时,PostgreSQL服务端在解析?占位符的阶段,无法自动推导占位符对应的明确数据类型;即使JDBC客户端已经声明参数类型为Types.TIMESTAMP,服务端的函数签名匹配阶段仍会将该占位符判定为unknown类型,最终无法匹配到合法的date_part函数签名,抛出函数不唯一的错误。

修复方案

在SQL语句中对传入的占位符做显式类型强转,强制指定参数为时间类型即可,不需要修改Java端的传参逻辑,修改后的SQL写法如下:

-- 转换为无时区时间戳
select extract(year from LOCALTIMESTAMP) - extract(year from ?::timestamp)

如果业务场景传入的是带时区的时间戳,也可以根据实际需求转换为带时区的时间戳类型:

-- 转换为带时区时间戳
select extract(year from LOCALTIMESTAMP) - extract(year from ?::timestamptz)

内容的提问来源于stack exchange,提问作者Леонид

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 10:30:55