Данный:
CREATE TABLE A (
PK_A INT8 NOT NULL,
A INT8,
PRIMARY KEY (PK_A)
);
CREATE TABLE B (
PK_B INT8 NOT NULL,
B INT8,
PRIMARY KEY (PK_B)
);
Этот запрос:
insert into table_b (pk_b, b)
select pk_a,a from table_a
on conflict (b) do update set b=a;
вызывает следующую ошибку:
ERROR: column "a" does not exist LINE 1: ...elect pk_a,a from table_a on conflict (b) do update set b=a; ^ HINT: There is a column named "a" in table "*SELECT*", but it cannot be referenced from this part of the query.
Как сделать обновление при обращении к содержанию table_a
?
postgresql
postgresql-9.5
upsert
Тони Индрали
источник
источник
CREATE TABLE A...
создает таблицуa
, а неtable_a
.do update set b = a;
не может найти «а» , потому что там ссылку на таблицу «Ъ» и не Подзапрос, попробуйтеdo update set b = (select a from a);
Ответы:
Множество проблем.
Ваша настройка, расширенная:
Это работает:
Результат:
Проблемы
Вы сбиваете с толку
table_a
иA
в своей демонстрации (как прокомментировал @Abelisto ).Использование легальных, строчных, без кавычек идентификаторов помогает избежать путаницы.
Как упоминалось @Ziggy ,
ON CONFLICT
работает только для фактических нарушений уникальных или исключающих ограничений . Руководство:Следовательно,
не может работать, никаких ограничений нет.ON CONFLICT (b)
ON CONFLICT (pk_b)
работает.Как и в случае @Ziggy , имена исходных таблиц не видны в этой
UPDATE
части. Руководство:Жирный акцент мой.
Вы также не можете использовать имена столбцов исходной таблицы в
UPDATE
детали. Это должны быть имена столбцов целевой строки . Итак, вы действительно хотите:Руководство еще раз:
источник
b = excluded.a
не может работать, это было немного спрятано в официальной документации.При выполнении upserts в PostgreSQL 9.5+ вы должны ссылаться на исключенные данные (те, которые не удалось вставить) по псевдониму
excluded
. Такжеon conflict
опция должна ссылаться на ключ:(pk_b)
вместо(b)
. Например.Для получения дополнительной информации обратитесь к официальной документации или этому простому введению upsert .
источник