OFFSET N FETCH FIRST M ROWS与JDBC和PostgreSQL无法正常工作

时间:2018-05-16 13:04:34

标签: java sql postgresql jdbc

我试图使用JDBC和PostgreSQL进行查询,但我面临着一种我无法在任何文档中找到的奇怪情况。

如果我通过pgAdmin和H2(我用于我的应用程序的单元测试)执行它,以下查询有效,但是如果我通过JDBC执行它会出现语法错误:

Queries.SELECT_SQL

SELECT columns 
  FROM Table 
  LEFT JOIN TableToJoin1 
  LEFT JOIN TableToJoin2 
  LEFT JOIN TableToJoin3 
  JOIN TableToJoin4

Queries.ENDING_PAGING_STATEMENT_SQL

OFFSET ? ROWS FETCH FIRST ? ROWS ONLY

SELECT查询是正确的,并且可以使用任何方法正常工作,问题是当我同时进行两个查询时,即SELECT语句以及OFFSET和{{1} }。

这就是我通过FETCH FIRST执行查询的方式:

JDBC

以下是抛出异常的消息:

// Receive offset and limit as argument.
try (final PreparedStatement selectStatement = connection
        .prepareStatement(Queries.SELECT_SQL + Queries.ENDING_PAGING_STATEMENT_SQL)) {

  selectStatement.setInt(Queries.PAGING_ENDING_STATEMENT_OFFSET_ARGUMENT_POSITION, offset);
  selectStatement.setInt(Queries.PAGING_ENDING_STATEMENT_LIMIT_ARGUMENT_POSITION, limit);

  final ResultSet resultSet = bookSelectStatement.executeQuery();
  ...
}

如果我调用org.postgresql.util.PSQLException: ERROR: syntax error at or near "$2" 进行调试,我会完全按照预期收到查询。

如果我将selectStatement.toString()改为OFFSET N ROWS FETCH FIRST M ROWS ONLY,它将通过JDBC工作而不会有任何问题。 最简单的解决方案将在上面进行简单的更改,但我的任务的一部分是使用此OFFSET N LIMIT M语句进行查询。

那么,你们可以帮助我看看我做错了,或者根本没有办法在JDBC上使用FETCH FIRST M ROWS ONLY的PostgreSQL吗?通过一些示例或对任何有用的文档的一些引用。

我注意到FETCH FIRSTFETCH FIRST并不存在,但由于它通过pgAdmin工作,我不知道为什么我在使用JDBC时会遇到任何问题。

非常感谢你!

1 个答案:

答案 0 :(得分:6)

我可以重现这个问题。从版本10开始,documentation说:

  

在这种语法中,要为start或count写一个除简单整数常量之外的任何东西,你必须在它周围写括号

当然,这是荒谬的。应该允许绑定变量没有括号 - 大多数数据库允许它们,PostgreSQL也接受android:roundIcon="@mipmap/ic_launcher_round"语法,但看起来它们不是PostgreSQL对标准SQL语法的解释。所以你必须写:

OFFSET ? LIMIT ?

I would consider this a bug, which I've reported here