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

Mag*_*nto 4 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
Run Code Online (Sandbox Code Playgroud)

Queries.ENDING_PAGING_STATEMENT_SQL

OFFSET ? ROWS FETCH FIRST ? ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

SELECT查询是正确的,使用任何手段工作正常,问题是当我拿到这两个查询一起,即SELECT沿语句OFFSETFETCH 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();
  ...
}
Run Code Online (Sandbox Code Playgroud)

以下是抛出异常的消息:

org.postgresql.util.PSQLException: ERROR: syntax error at or near "$2"
Run Code Online (Sandbox Code Playgroud)

如果我打电话selectStatement.toString()给调试,我会完全按照我的预期收到查询.

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

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

我注意到PostgreSQL文档FETCH FIRST中不存在:查询 - 偏移和限制,但由于它通过pgAdmin工作,我不知道为什么我应该在使用JDBC时遇到任何问题.

非常感谢!

Luk*_*der 6

我可以重现这个问题.从版本10开始,文档说:

在这种语法中,要编写除开始或计数的简单整数常量之外的任何内容,必须在其周围编写括号

当然,这很荒谬.应该允许绑定变量没有括号 - 大多数数据库允许它们,并且OFFSET ? LIMIT ?PostgreSQL也接受语法,但看起来它们不是PostgreSQL对标准SQL语法的解释.所以你必须写:

OFFSET (?) ROWS FETCH FIRST (?) ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

我认为这是一个错误,我在这里报告过