Nhiều vấn đề.
Thiết lập của bạn, được mở rộng:
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');
Những công việc này:
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
Kết quả:
TABLE b;
pk_b | b | comment
------+----+----------------
1 | 11 | comment from b -- updated
2 | 22 | comment from a -- inserted
Vấn đề
Bạn đang bối rối table_avà Atrong bản demo của bạn (như @Abelisto đã nhận xét ).
Sử dụng định danh hợp pháp, chữ thường, không trích dẫn giúp tránh nhầm lẫn.
Giống như @Ziggy đã đề cập , ON CONFLICTchỉ hoạt động đối với các vi phạm ràng buộc duy nhất hoặc loại trừ thực tế . Hướng dẫn sử dụng:
Điều ON CONFLICTkhoản tùy chọn chỉ định một hành động thay thế để nâng cao lỗi vi phạm ràng buộc hoặc loại trừ vi phạm duy nhất.
Do đó, ON CONFLICT (b)không thể làm việc, không có ràng buộc ở đó. ON CONFLICT (pk_b)làm.
Giống như @Ziggy cũng đề cập đến , nguồn tên bảng không nhìn thấy được trong UPDATEmột phần. Hướng dẫn sử dụng:
Các SETvà WHEREcác điều khoản trong ON CONFLICT DO UPDATEcó quyền truy cập vào hàng hiện có sử dụng tên của bảng (hoặc một bí danh), và hàng đề xuất cho chèn bằng cách sử dụng đặc biệt excludedbảng .
Nhấn mạnh đậm của tôi.
Bạn cũng không thể sử dụng tên cột của bảng nguồn trong UPDATEphần. Nó phải là tên cột của hàng đích . Vì vậy, bạn thực sự muốn:
SET b = excluded.b
Hướng dẫn một lần nữa:
Lưu ý rằng các hiệu ứng của tất cả các BEFORE INSERTkích hoạt trên mỗi hàng được phản ánh trong các giá trị bị loại trừ, vì các hiệu ứng đó có thể đã góp phần khiến hàng bị loại khỏi chèn.
CREATE TABLE A...tạo bảnga, khôngtable_a.