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_a
dan A
dalam demo Anda (seperti komentar @Abelisto ).
Menggunakan pengidentifikasi legal, huruf kecil, tanda kutip membantu menghindari kebingungan.
Seperti @Ziggy yang disebutkan , ON CONFLICT
hanya berfungsi untuk pelanggaran batasan unik atau pengecualian . Manual:
ON CONFLICT
Klausa 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 UPDATE
bagian itu. Manual:
The SET
dan WHERE
klausa dalam ON CONFLICT DO UPDATE
memiliki akses ke baris yang sudah ada menggunakan nama tabel (atau alias), dan untuk baris diusulkan untuk penyisipan menggunakan khusus excluded
tabel .
Penekanan berani saya.
Anda juga tidak bisa menggunakan nama kolom dari tabel sumber di UPDATE
bagian 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 INSERT
pemicu 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
.