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_a
và A
trong 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 CONFLICT
chỉ 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 CONFLICT
khoả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 UPDATE
một phần. Hướng dẫn sử dụng:
Các SET
và WHERE
các điều khoản trong ON CONFLICT DO UPDATE
có 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 excluded
bả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 UPDATE
phầ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 INSERT
kí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
.