Pg-jdbc在现有RETURNING子句的准备批处理上附加RETURNING *

时间:2016-01-01 22:24:20

标签: jdbc prepared-statement postgresql-9.4 jdbi pg-jdbc

我正在使用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>

2 个答案:

答案 0 :(得分:1)

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

如果你想使用RETURNING id作为某种优化,那么你需要找出JDBI是否有一个访问Connection.preparedStatement(String query, String[] columnNames)的API(据我所知,它不是&#39;有))。

只有其他选项是提交pgjdbc的改进请求。

答案 1 :(得分:0)

使用connection.prepareStatement(sql)代替connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)