Java 偏移量N获取前M行,JDBC和PostgreSQL不工作

Java 偏移量N获取前M行,JDBC和PostgreSQL不工作,java,sql,postgresql,jdbc,Java,Sql,Postgresql,Jdbc,我试图使用JDBC和PostgreSQL进行查询,但我面临着一个在任何文档中都找不到的奇怪情况 如果通过pgAdmin和H2(我在应用程序的单元测试中使用它)执行,则以下查询可以工作,但如果通过JDBC执行,则会出现语法错误: 查询。选择\u SQL SELECT columns FROM Table LEFT JOIN TableToJoin1 LEFT JOIN TableToJoin2 LEFT JOIN TableToJoin3 JOIN TableToJo

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

如果通过pgAdmin和H2(我在应用程序的单元测试中使用它)执行,则以下查询可以工作,但如果通过JDBC执行,则会出现语法错误:

查询。选择\u SQL

SELECT columns 
  FROM Table 
  LEFT JOIN TableToJoin1 
  LEFT JOIN TableToJoin2 
  LEFT JOIN TableToJoin3 
  JOIN TableToJoin4
OFFSET ? ROWS FETCH FIRST ? ROWS ONLY

查询。结束\u分页\u语句\u SQL

SELECT columns 
  FROM Table 
  LEFT JOIN TableToJoin1 
  LEFT JOIN TableToJoin2 
  LEFT JOIN TableToJoin3 
  JOIN TableToJoin4
OFFSET ? ROWS FETCH FIRST ? ROWS ONLY

SELECT
查询是正确的,使用任何方法都可以正常工作,问题是当我将两个查询放在一起时,即
SELECT
语句以及
OFFSET
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 LIMIT M
更改
OFFSET N ROWS仅获取前M行
,它将通过JDBC正常工作。 最简单的解决方案是进行上面的简单更改,但我的部分任务是使用
fetchfirstm ROWS ONLY
语句进行查询

所以,你们能帮我看看我是不是做错了,还是根本没有办法在JDBC for PostgreSQL上使用
FETCH FIRST
?提供一些示例或参考任何有帮助的文档

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


非常感谢你

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

在这种语法中,要为start或count写入除简单整数常量之外的任何内容,必须在其周围写上括号

这当然是荒谬的。应该允许绑定变量不带括号-大多数数据库都允许它们和
偏移?限制?
语法也被PostgreSQL接受,但看起来它们似乎不在PostgreSQL对标准SQL语法的解释中。所以你必须写:

OFFSET (?) ROWS FETCH FIRST (?) ROWS ONLY

fetch first
是关于-的章节中的文档,看起来像是文档错误,而且您不能在
PreparedStatement
中提供限制/偏移量作为可分配参数。事实上,这可能不再是真的,这取决于驱动程序。谢谢你@a_horse_,没有名字,它被隐藏在索引中,但看起来我对查询没有做错任何事情。@Kayaman,但是如果我更改
OFFSET N ROWS只取前m行
OFFSET N LIMIT m
,它会正常工作,如果不更改
PreparedStatement
上的任何内容,为什么会有所不同?似乎
PreparedStatement
确实允许参数化限制/偏移,但我可以发誓我以前在这方面遇到过麻烦。我可能正在考虑一些模糊层,但它不允许这样。哦,我正在使用它,我只是忘了在问题上写它,谢谢。但不管有没有这个关键字,我都会犯同样的错误。什么?可以这真的很有帮助,我在课上没有任何关于它的笔记,所以这是一个新的、意想不到的东西。谢谢,它现在可以正常工作了!“看起来它们不符合标准SQL语法”SQL标准允许文本或参数(但不允许列等),不允许表达式。从技术上讲,标准甚至不允许使用括号。(SQL:2016-27.17)@a_horse_和_no_name:我已经恢复了您的更改并添加了一个清晰的版本指示器。我相信这是一个应该被修复的bug,所以在将来,手册可能会说些什么different@MarkRotteveel:是的,修正了我的措辞。我不是这个意思