Berbagai masalah.
Pengaturan Anda, diperluas:
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');
Ini bekerja:
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
Hasil:
TABLE b;
pk_b | b | comment
------+----+----------------
1 | 11 | comment from b -- updated
2 | 22 | comment from a -- inserted
Masalah
Anda membingungkan table_adan Adalam demo Anda (seperti komentar @Abelisto ).
Menggunakan pengidentifikasi legal, huruf kecil, tanda kutip membantu menghindari kebingungan.
Seperti @Ziggy yang disebutkan , ON CONFLICThanya berfungsi untuk pelanggaran batasan unik atau pengecualian . Manual:
ON CONFLICTKlausa opsional menentukan tindakan alternatif untuk meningkatkan kesalahan unik pelanggaran atau pengecualian pelanggaran batasan.
Akibatnya, ON CONFLICT (b)tidak bisa bekerja, tidak ada kendala di sana. ON CONFLICT (pk_b)bekerja.
Seperti @Ziggy juga disebutkan , nama tabel sumber tidak terlihat di UPDATEbagian itu. Manual:
The SETdan WHEREklausa dalam ON CONFLICT DO UPDATEmemiliki akses ke baris yang sudah ada menggunakan nama tabel (atau alias), dan untuk baris diusulkan untuk penyisipan menggunakan khusus excludedtabel .
Penekanan berani saya.
Anda juga tidak bisa menggunakan nama kolom dari tabel sumber di UPDATEbagian tersebut. Itu harus nama kolom dari baris target . Jadi, Anda benar-benar ingin:
SET b = excluded.b
Manual sekali lagi:
Perhatikan bahwa efek dari semua BEFORE INSERTpemicu setiap baris dicerminkan dalam nilai yang dikecualikan, karena efek tersebut mungkin berkontribusi pada baris yang dikecualikan dari penyisipan.
CREATE TABLE A...membuat tabela, bukantable_a.