複数の問題。
拡張されたセットアップ:
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
and WHERE
句はON CONFLICT DO UPDATE
、テーブルの名前(またはエイリアス)を使用して既存の行にアクセスし、特別なexcluded
テーブルを使用して挿入が提案された行にアクセスします。
大胆な強調鉱山。
また、ソーステーブルの列名をUPDATE
パーツで使用することもできません。ターゲット行の列名でなければなりません。あなたは本当に欲しい:
SET b = excluded.b
もう一度マニュアル:
すべての行ごとのBEFORE INSERT
トリガーの効果は、除外された値に反映されることに注意してください。これらの効果は、挿入から除外される行に寄与している可能性があるためです。
CREATE TABLE A...
a
ではなく、テーブルを作成しますtable_a
。