在Java中,我使用java.sql.PreparedStatement
尝试提交一个相当大的查询,其中包含恒定的(VALUES (?), (?), (?)...)
表达式以实现高效连接。
有cca 250K值,所以我还要设置250K参数。
在Java中,
org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.
在我的服务器PostgreSQL日志上,只有一行关于该错误:
incomplete message from client
关于可以随时更改以使大型查询正常工作的某些设置的想法吗?
最佳答案
JDBC驱动程序可以传递给后端的最大参数数是32767。这受v3有线协议的限制,该协议以16位int形式传递参数计数(有关definition of the Bind message的信息,请参阅文档)。
您可以通过在数组中传递值并将其取消嵌套在服务器上来解决此问题:
// Normally this would be one too many parameters
Integer[] ids = new Integer[Short.MAX_VALUE + 1];
Arrays.setAll(ids, i -> i);
// Pass them in an array as a single parameter and unnest it
PreparedStatement stmt = con.prepareStatement(
"WITH ids (id) AS (SELECT unnest (?)) " +
"SELECT f.* FROM foo f JOIN ids i ON i.id = f.id"
);
stmt.setArray(1, con.createArrayOf("INT", ids));