Мы используем Derby, и у нас много кода, который выглядит примерно так:
try (ResultSet rs = executeQuery(...)) {
if (rs.next()) {
updateRowSet(rs, ...);
rs.updateRow();
} else {
executeUpdate(...);
}
}
Раньше мы искали способ реализовать эту логику на стороне сервера и обнаружили, что некоторые базы данных поддерживают операцию «upsert» (обновление или вставка). У Дерби был запрос функции для MERGE INTO
, который предположительно был стандартным способом выполнения этого в SQL: 2003, поэтому мы сидели и смотрели заявку, и прошло много времени.
Наконец, Derby 10.11 добавил MERGE INTO
. Никто еще не успел просмотреть и обновить код, чтобы использовать его, но при чтении их документации все их примеры показывают слияние одной таблицы с другой. Но подождите, наших данных еще нет в таблице!
Я знаю, что могу поместить его в таблицу, но тогда это снова несколько запросов, что полностью лишает смысла его использование.
Я уверен, что это можно сделать без помещения его в таблицу, но поскольку в документации нет ни одного примера, я не знаю, как действовать дальше.
Вот что я пробовал:
try (PreparedStatement ps = connection.prepareStatement(
"MERGE INTO things AS target " +
// Awkward point 1:
// It wants a "source" table, but I don't have one.
// So I thought I would try to use the same table with
// another name.
" USING things AS source ON target.id = ?" +
" WHEN MATCHED THEN" +
" UPDATE SET data = ?" +
" WHEN NOT MATCHED THEN" +
" INSERT (id, data) VALUES (??, ?)"))
{
ps.setLong(1, id);
ps.setBinaryStream(2, data);
ps.setLong(3, id);
// Awkward point 2:
// Passing an InputStream into a query as two
// parameters.
ps.setBinaryStream(4, data);
ps.execute();
}
Похоже, что это не делает никаких вставок, но также не дает ошибок, так что мне абсолютно нечего делать.