如何将多个值作为参数的sql数组传递?(或者我怎样才能规避准备好的语句的参数限制?

How to pass multiple values as sql array for a parameter? (Or how can I circumvent the limit of parameters of prepared statement?)

提问人:domids 提问时间:11/10/2023 最后编辑:domids 更新时间:11/14/2023 访问量:45

问:

我正在尝试使用 QueryDSL 创建一个查询,该查询接受超过 32767 个参数(32767 是 PostgreSQL 驱动程序接受的参数上限)。

查询当前创建如下:

static final QInvoiceEntity invoiceEntity = ...

void queryInvoicesWithId(String... ids) {
  JPAQuery query = ...
  query.where(invoiceEntity.id.in(ids));
}

如果传递的参数不超过 32767 个,则此方法有效。如果传递超过该值(例如 38000),则会引发以下异常:

Caused by: java.io.IOException: Tried to send an out-of-range integer as a 2-byte value: 38000
        at org.postgresql.core.PGStream.sendInteger2(PGStream.java:275)

根据 1 的一个解决方案是使用参数并将其作为数组传递。我尝试了以下方法,但无济于事:ANY

query.where(Expressions.booleanTemplate("{0} = ANY {1}", invoiceEntity.id, ids);

但这会引发以下异常:

org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ? near line 3, column 31 [select invoiceEntity
from InvoiceEntity invoiceEntity
where invoiceEntity.id = ANY (?1)

我什至尝试将参数作为字符串传递并在查询中将其转换回:

query.where(Expressions.booleanTemplate("{0} = ANY string_to_array({1}, ',')", invoiceEntity.id, String.join(",", ids));

但这会引发以下异常:

org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 3, column 45 [select invoiceEntity
from InvoiceEntity invoiceEntity
where invoiceEntity.id = ANY string_to_array(?1, ',')
java postgresql 休眠 jpa 查询dsl

评论

1赞 Rodolphe 11/10/2023
您的 38k 参数的来源是什么?如果它们来自您之前进行的另一个查询,则应更改代码并使用 CTE 或其他 SQL 语法来读取数据并在单个操作中推送它们。
1赞 Rodolphe 11/10/2023
如果数据来自外部,另一种解决方案是使用命令 COPY 填充临时表,并进行将读取临时表的符号查询
0赞 domids 11/14/2023
@Rodolphe 是的,源是另一个查询。谢谢你的想法!

答: 暂无答案