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