Pg-jdbc добавляет RETURNING * к подготовленной партии с существующим предложением RETURNING
Я выполняю подготовленную пакетную вставку в таблицу Postgres, используя pg-jdbc/JDBI, чтобы получить список сгенерированных значений идентификатора, используя явное предложение RETURNING:
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 ответа
Ты используешь 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)