Множинні проблеми.
Ваша установка, розширена:
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.