Pg-jdbc 将 RETURNING * 添加到已准备好的批次中,并带有现有的 RETURNING 子句
Pg-jdbc Appends RETURNING * on Prepared Batch wtih Existing RETURNING Clause
我正在使用 pg-jdbc/JDBI 执行准备好的批量插入到 Postgres table 中,以便使用显式 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 子句,该语句可以正常工作;但是,它会导致返回目标 table 中的所有字段,这在插入大量数据的许多情况下是非常不受欢迎的。
有什么方法可以阻止 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>
您正在使用 executeAndGenerateKeys
,这很可能会使用 Connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)
。在这种情况下,PostgreSQL JDBC 的生成键实现将附加 RETURNING *
到查询(它不检查它是否已经存在于查询文本中)。您需要从自己的查询中删除 RETURNING id
才能使其正常工作。
如果你想使用 RETURNING id
作为某种优化,那么你需要找出 JDBI 是否有一个 API 来访问 Connection.preparedStatement(String query, String[] columnNames)
(据我所知告诉它没有)。
唯一的选择是提交 pgjdbc 的改进请求。
使用connection.prepareStatement(sql)
代替connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)
我正在使用 pg-jdbc/JDBI 执行准备好的批量插入到 Postgres table 中,以便使用显式 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 子句,该语句可以正常工作;但是,它会导致返回目标 table 中的所有字段,这在插入大量数据的许多情况下是非常不受欢迎的。
有什么方法可以阻止 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>
您正在使用 executeAndGenerateKeys
,这很可能会使用 Connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)
。在这种情况下,PostgreSQL JDBC 的生成键实现将附加 RETURNING *
到查询(它不检查它是否已经存在于查询文本中)。您需要从自己的查询中删除 RETURNING id
才能使其正常工作。
如果你想使用 RETURNING id
作为某种优化,那么你需要找出 JDBI 是否有一个 API 来访问 Connection.preparedStatement(String query, String[] columnNames)
(据我所知告诉它没有)。
唯一的选择是提交 pgjdbc 的改进请求。
使用connection.prepareStatement(sql)
代替connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)