У меня проблема с использованием UPSERT в Postgresql 9.5.
У меня есть таблица с 50 столбцами, и мои ключи агрегации содержат 20 ключей, из которых 15 могут быть нулевыми.
Итак, это моя таблица:
CREATE TABLE public.test
(
id serial NOT NULL,
stamp timestamp without time zone,
foo_id integer,
bar_id integer,
...
CONSTRAINT id_pk PRIMARY KEY (id),
CONSTRAINT test_agg_key_unique UNIQUE (stamp, foo_id, bar_id, ...)
);
После я создам частичный индекс с моим ключом агрегации. Но перед этим мне нужно создать уникальное ограничение, потому что не все ключи NOT NULL
alter table public.test ADD CONSTRAINT test_agg_key_unique UNIQUE (stamp, foo_id, bar_id, ...);
Потом:
CREATE UNIQUE INDEX test_agg_key on lvl1_conversion.conversion (coalesce(stamp, '1980-01-01 01:01:01'), coalesce(foo_id, -1), coalesce(bar_id, -1), ...);
И теперь я могу выполнить свой UPSERT
:
INSERT INTO public.test as t (id, stamp, foo_id, bar_id, ...)
VALUES (RANDOM_ID, '2016-01-01 01:01:01', 1, 1, ...)
ON CONFLICT (stamp, foo_id, bar_id, ...)
do update set another_column = t.another_column + 1
where t.stamp = '2016-01-01 01:01:01' and t.foo_id = 1 and t.bar_id= 1 and ...;
Поэтому, если ключ агрегации уже существует, он обновит строку, если она вставит новую строку. Но когда я использую тот же запрос, но с одним или несколькими значениями null
, я получаю следующее исключение:
ERROR: duplicate key value violates unique constraint "test_agg_key_unique"
Из-за этого исключения он никогда не вызывает do update
Еще один хороший пример: https://dba.stackexchange.com/questions/151431/postgresql-upsert-issue-with-null-values