日期截取 org.postgresql.util.PSQLException: 错误:"$1" 附近有语法错误。

9

我运行这个Java/JDBC代码时遇到了这个错误。有没有想法如何解决它?

看起来它在抱怨 date_trunc 函数中的参数?

org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1" Position: 100

        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryEx
ecutorImpl.java:2161)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutor
Impl.java:1890)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.ja
va:255)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Stat
ement.java:560)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(Abstract
Jdbc2Statement.java:417)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc
2Statement.java:302)

Java 代码:

static PreparedStatement searchErrorPP = connection.prepareStatement(
"select count(*) from tracking where date_trunc('day', run_date) <= 
     date_trunc('day', timestamp ?)");



public static int queryCount(java.util.Date date) throws SQLException {


  PreparedStatement ps = null;
  try {
      ps = searchErrorPP;
      ps.setDate( 1, new java.sql.Date(date.getTime()));
      ResultSet rs = ps.executeQuery();

在pgAdmin中执行正常的查询结果:

select count(*) from tracking where date_trunc('day', run_date) <= 
           date_trunc('day', timestamp '2014-11-11 -05:00:00')

你能简化查询,只需触发错误吗?当你已经有日期时,你真的需要使用时间戳转换和 date_trunc 吗?PostgreSQL 本地使用编号占位符 $1$2 等,因此 ? 占位符在内部可能被转换为编号占位符,因此错误消息中出现了 $2 - mu is too short
@mu 太短了:好的,我更新了问题并缩短了查询。 - Say No To Censorship
@mu 太短了:我正在将针对 Oracle 的特定 Java 代码移植到 Postgres,因此我用 Postgres 的 date_trunc 替换了 Oracle 的 trunc 以实现相同的结果。原则上查询运行良好,因此我正在尝试将其集成到 Java 中。如果不起作用,我可能会尝试您所说的直接使用 Date 对象而不是使用 date_trunc。 - Say No To Censorship
使用?::timestampcast(? as timestamp)是否更好?我没有设置所有的Java东西,所以我只是猜测。 - mu is too short
我更新了发布的Java异常,'receiveErrorResponse'是指查询执行成功但后处理失败吗? - Say No To Censorship
显示剩余2条评论
2个回答

15

当使用type 'string'语法,例如timestamp '2014-11-11 -05:00:00'时,提供的值必须是一个常量,而不是参数。在实际执行之前,在解析阶段,SQL引擎会将其解释并转换为内部时间戳表示。

因此,当遇到timestamp $1时,解析器会产生语法错误,因为$1不是字面字符串。

另一方面,cast($1 as timestamp)的值将在执行阶段生成,因此应该使用它。

至于JDBC的语法,cast(? as timestamp)应该没问题。 PostgreSQL特定的语法?::timestamp也可能有效。


cast(? as timestamp) 已经生效,感谢您的解释!@mu is too short 也提出了同样的建议,但我放弃得有点早。 - Say No To Censorship
“?::timestamp” 对我没用,它在独立查询中可以工作,但通过JDBC却不能。 - Say No To Censorship
@sv. ::type 语法是 PostgreSQL 特有的转换,因此在 JDBC 中可能会引起混淆。cast(? as type) 是标准 SQL。无论如何,很高兴你已经解决了这个问题。 - mu is too short
谢谢,我也遇到了INTERVAL的问题,使用cast(:seasonInterval as INTERVAL)可以正常工作。 - Eric Taix

0

当jdbc连接url组件为空时,我看到过这样的错误。

例如,连接url组件例如DB主机名、dbname、用户或密码为空。

请检查一下,你应该能够找到线索。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接