Pg jdbc使用现有的RETURNING子句在准备好的批次上附加RETURNING*



我正在使用pg jdbc/JDBI执行一个准备好的批处理插入到Postgres表中,以便使用显式RETURNING子句获得生成的id值列表:

PreparedBatch b = getHandle().prepareBatch("INSERT INTO death_star(id,exhaust_port) VALUES ( :id, :exhaust_port) RETURNING id;");
for (RebelPilot p : rebelPilots) {
    b.add().bind("id",p.getId()).bind("exhaust_port",p.getProtonTorpedo());
}
ResultSetMapper<Long> mapper = new IdMapper()
GeneratedKeys<Long> gk = b.executeAndGenerateKeys(mapper);
return gk.list()

当准备好该语句时,pg jdbc将无意识地在现有的RETURNING子句后面附加一个额外的RETURNING *,从而导致以下格式错误的可憎行为:

INSERT INTO death_star(id,exhaust_port) VALUES ( ?, ?) RETURNING id RETURNING *;

如果删除显式的RETURNING子句,则该语句工作正常;然而,它会导致返回目标表中的所有字段,这在许多插入了大量数据的情况下是非常不希望的。

有什么方法可以阻止pg jdbc参与这种行为吗?

测试相关性:

<dependency>
  <groupId>org.postgresql</groupId>
  <artifactId>postgresql</artifactId>
  <version>9.4.1207.jre7</version>
</dependency>
<dependency>
  <groupId>org.jdbi</groupId>
  <artifactId>jdbi</artifactId>
  <version>2.71</version>
</dependency>

您使用的是可能使用Connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)executeAndGenerateKeys。在这种情况下,PostgreSQL JDBC的生成密钥实现会将RETURNING *附加到查询中(它不会检查它是否已经存在于查询文本中)。您需要从自己的查询中删除RETURNING id才能使其工作。

如果您想使用RETURNING id作为某种优化,那么您需要了解JDBI是否有访问Connection.preparedStatement(String query, String[] columnNames)的API(据我所知,它没有)。

唯一的其他选择是为pgjdbc提交改进请求。

使用connection.prepareStatement(sql)而不是connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)

相关内容

  • 没有找到相关文章

最新更新