大型查询上的Java PostgreSQL错误:发送到后端时发生I/O错误

大型查询上的Java PostgreSQL错误:发送到后端时发生I/O错误,java,postgresql,jdbc,limits,Java,Postgresql,Jdbc,Limits,在Java中,使用Java.sql.PreparedStatement,我试图提交一个相当大的查询,其中包含常量(值(?),(?),(?)…)表达式以实现高效联接 有cca 250K值,所以我也设置了250K参数 在Java中,我得到了 org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend. 在我的服务器PostgreSQL日志中,有一行关于该错误的信息: incomplete

在Java中,使用
Java.sql.PreparedStatement
,我试图提交一个相当大的查询,其中包含常量
(值(?),(?),(?)…)
表达式以实现高效联接

有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 wire协议的限制,该协议以16位整数传递参数计数(有关详细信息,请参阅文档)

您可以通过在数组中传递值并在服务器上取消对它们的测试来解决此问题:

// 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));

您正试图执行一个带有250000个参数的
PreparedStatement
?这是你的问题。尝试创建一个临时文件。表,而是对该表使用批处理插入,然后使用临时连接。安德烈,我明白你的意思了,谢谢你,我可能不得不这样做了。我知道250K是一个很大的数目,但是,只要计算机没有情绪,我一定会达到某个极限。我的问题是关于这个限制,以及我是否可以提高它。我已经读到psql查询大小限制是1GB,但我的参数是短标识符,它必须在其他地方…限制可能取决于JDBC驱动程序;将限制设置为2k。我同意安德烈亚斯的观点;使用带有
addBatch()
的普通插入或驱动程序支持的其他批插入变体。@Mick助记符它不像驱动程序那么重要,但主要是服务器的限制。驾驶员可能只是预先执行限制,有时会稍微降低。例如,MS SQL 2016每个存储过程最多有2100个参数(请参阅),我相信JDBC驱动程序将临时存储过程用于PreparedStatements。