Множество проблем.
Ваша настройка, расширенная:
CREATE TABLE a (
pk_a int PRIMARY KEY
, a int
, comment text -- added column to make effect clear
);
CREATE TABLE b (
pk_b int PRIMARY KEY
, b int
, comment text
);
INSERT INTO a VALUES (1, 11, 'comment from a')
, (2, 22, 'comment from a');
INSERT INTO b VALUES (1, 77, 'comment from b');
Это работает:
INSERT INTO b (pk_b, b, comment)
SELECT pk_a, a, comment
FROM a
ON CONFLICT (pk_b) DO UPDATE -- conflict is on the unique column
SET b = excluded.b; -- key word "excluded", refer to target column
Результат:
TABLE b;
pk_b | b | comment
------+----+----------------
1 | 11 | comment from b -- updated
2 | 22 | comment from a -- inserted
Проблемы
Вы сбиваете с толку table_a
и A
в своей демонстрации (как прокомментировал @Abelisto ).
Использование легальных, строчных, без кавычек идентификаторов помогает избежать путаницы.
Как упоминалось @Ziggy , ON CONFLICT
работает только для фактических нарушений уникальных или исключающих ограничений . Руководство:
Необязательное ON CONFLICT
предложение определяет альтернативное действие по отношению к выдаче уникальной ошибки нарушения или нарушения ограничения исключения.
Следовательно, ON CONFLICT (b)
не может работать, никаких ограничений нет. ON CONFLICT (pk_b)
работает.
Как и в случае @Ziggy , имена исходных таблиц не видны в этой UPDATE
части. Руководство:
SET
И WHERE
положение в ON CONFLICT DO UPDATE
имеет доступ к существующей строке с использованием имени таблицы (или псевдонима) и строки , предложенных для вставки с помощью специальной excluded
таблицы .
Жирный акцент мой.
Вы также не можете использовать имена столбцов исходной таблицы в UPDATE
детали. Это должны быть имена столбцов целевой строки . Итак, вы действительно хотите:
SET b = excluded.b
Руководство еще раз:
Обратите внимание, что эффекты всех BEFORE INSERT
триггеров для каждой строки отражаются в исключенных значениях, поскольку эти эффекты могли способствовать исключению строки из вставки.
CREATE TABLE A...
создает таблицуa
, а неtable_a
.