Мне нужно UPSERT
Функциональность в Postgres. Поскольку Postgres не поддерживает это изначально, я написал функцию, которая делает это (пытается обновить, если ни одна строка не была обновлена затем вставляет)Пакетное обновление в Postgresql
Это шаблон для функции: https://stackoverflow.com/a/1109198/681671
CREATE FUNCTION merge_db(key INT, data TEXT) RETURNS VOID AS
$$
BEGIN
LOOP
-- first try to update the key
UPDATE db SET b = data WHERE a = key;
IF found THEN
RETURN;
END IF;
-- not there, so try to insert the key
-- if someone else inserts the same key concurrently,
-- we could get a unique-key failure
BEGIN
INSERT INTO db(a,b) VALUES (key, data);
RETURN;
EXCEPTION WHEN unique_violation THEN
-- do nothing, and loop to try the UPDATE again
END;
END LOOP;
END;
$$
LANGUAGE plpgsql;
SELECT merge_db(1, 'david');
Я используя шаблон Spring JDBC. Этот оператор select (в его параметризованной форме) и массив объектов - это то, что я передаю методу batchUpdate для JDBCTemplate.
Я получаю это исключение:
org.postgresql.util.PSQLException: A result was returned when none was expected.
Я подозреваю, что это из-за использования SELECT
.
Я знаю, что могу использовать Callable в цикле, но это сделает приложение очень частым, а латентность ввода-вывода сделает его очень медленным.
Как выполняется пакетное обновление в Postgres с использованием Spring JDBC/raw JDBC?
Я использую Postgresql 9.1.
См. Http://stackoverflow.com/search?q=%5Bpostgresql%5D%20upsert –
@CraigRinger: Спасибо, попробуем это.Но все еще ищете подтверждение того, что несколько параметризованных вызовов процедуры не могут быть загружены при использовании JDBC + Postgres. Я видел метод addBatch для интерфейса Statement, и он делает что-то похожее на то, что я хочу, но не принимает параметры. Нужно сериализовать параметры в коде приложения и предоставить строку SQL. Существует много параметров, и каждый из них может быть подвержен ошибкам. – Dojo
Не могли бы вы показать нам, как вы вызываете функцию из Java? – MatheusOl