Я выполняю подготовленную вставку пакета в таблицу Postgres, используя pg-jdbc/JDBI, чтобы получить список сгенерированных значений id, используя явное предложение RETURNING:Pg-jdbc добавляет RETURNING * в подготовленную партию с существующим пунктом 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()
Когда готовят заявление, пг-JDBC будет бездумно добавить дополнительный RETURNING *
после существующего RETURNING
пункта приводит к следующему искаженной мерзости:
INSERT INTO death_star(id,exhaust_port) VALUES (?, ?) RETURNING id RETURNING *;
Если я удалить явную получать отдачу NG, заявление отлично работает; однако он возвращает ВСЕ поля из целевой таблицы, что крайне нежелательно во многих ситуациях, когда вставляются большие объемы данных.
Есть ли способ остановить 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>
При использовании обычного JDBC 'Connection.prepareStatement (String)' будет ** не ** добавьте 'returning' пункт. Поэтому я предполагаю, что метод 'prepareBatch()' вызывает вызовы, например. ['Connection.prepareStatement (String, int)'] (http://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#prepareStatement-java.lang.String-int-) , Можете ли вы научить этот метод делать «обычную» подготовку? Я не знаю, что делает 'executeAndGenerateKeys()' делает. Но с помощью простого JDBC вы просто вызываете 'execute()', а затем получаете сгенерированные ключи с помощью 'getResultSet()' из 'PreparedStatement' –
. Я не понимаю, почему добавление« RETURNING * »в качестве дополнения по умолчанию будет недействительным глобальный вариант, чтобы изменить его, особенно когда предложение 'RETURNING' уже присутствует в заявлении. Возможно, мне нужно записать проблему на pg-jdbc и JDBI. Кажется, что нет способа обойти это поведение с подготовленной партией JDBI. Согласно [this] (https://github.com/2ndQuadrant/pgjdbc/commit/1471bd93fce5401c8bc80f686f8beace9572ec79) pg-jdbc фактически не выполняет пакетную обработку, если целевые таблицы содержат массивы или неограниченные текстовые столбцы, поэтому я не уверен, что есть пункт для начала, – THX1138
Это обсуждалось в списке рассылки JDBC. При использовании 'prepareStatement (String, int)' драйвер должен будет проанализировать инструкцию, чтобы узнать, какие столбцы будут возвращены. Но у вас есть возможность изменить это (в JDBC). Если вы используете 'prepareStatement (String, String []), то драйвер вернет только указанные столбцы (я не знаю, сможет ли ваш слой обфускации сделать это) –