Java 偏移量N获取前M行,JDBC和PostgreSQL不工作
我试图使用JDBC和PostgreSQL进行查询,但我面临着一个在任何文档中都找不到的奇怪情况 如果通过pgAdmin和H2(我在应用程序的单元测试中使用它)执行,则以下查询可以工作,但如果通过JDBC执行,则会出现语法错误: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
查询。选择\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:是的,修正了我的措辞。我不是这个意思