postgresql 9.5でのupsertの正しい構文、以下のクエリはcolumn reference "gallery_id" is ambiguous
エラー、なぜですか?
var dbQuery = `INSERT INTO category_gallery (
category_id, gallery_id, create_date, create_by_user_id
) VALUES ($1, $2, $3, $4)
ON CONFLICT (category_id)
DO UPDATE SET
category_id = $1,
last_modified_date = $3,
last_modified_by_user_id = $4
WHERE gallery_id = $2`;
変更しようとしましたWHERE gallery_id = $2;
からWHERE category_gallery.gallery_id = $2;
はエラーを表示しますthere is no unique or exclusion constraint matching the ON CONFLICT specification
、しかしgallery_idまたはcategory_idを一意に設定したくない両方の列が同じであることを確認してから更新を行うため...
Postgres 9.5でアップサートを正しく行う方法は?
if ON CONFLICT
一意の列が必要ですが、他の方法を使用する必要がありますか?
複数の列の両方が競合していることを確認してから更新を行いたいのですが、正しい使い方は何ですか
var dbQuery = `INSERT INTO category_gallery (
category_id, gallery_id, create_date, create_by_user_id
) VALUES ($1, $2, $3, $4)
ON CONFLICT (category_id, gallery_id)
DO UPDATE SET
category_id = $1,
last_modified_date = $3,
last_modified_by_user_id = $4
WHERE gallery_id = $2`;
var dbQuery = `INSERT INTO category_gallery (
category_id, gallery_id, create_date, create_by_user_id
) VALUES ($1, $2, $3, $4)
ON CONFLICT (category_id AND gallery_id)
DO UPDATE SET
category_id = $1,
last_modified_date = $3,
last_modified_by_user_id = $4
WHERE gallery_id = $2`;
テーブル(category_id、gallery_idは一意の列ではありません)
category_id | gallery_id | create_date | create_by_user_id | last_modified_date | last_modified_by_user_id
1 | 1 | ...
1 | 2 | ...
2 | 2 | ...
1 | 3 | ...
ON CONFLICT
コンストラクトを使用するには、UNIQUE
制約が必要です。 INSERT .. ON CONFLICT
句 :
オプションの
ON CONFLICT
句は、一意違反または除外制約違反エラーを発生させる代替アクションを指定します。挿入が提案された個々の行ごとに、挿入が続行されるか、conflict_targetで指定されたアービター制約またはインデックスに違反した場合、代替のconflict_actionが実行されます。ON CONFLICT DO NOTHING
は、代替アクションとして行を挿入することを単に回避します。ON CONFLICT DO UPDATE
は、代替アクションとして挿入が提案された行と競合する既存の行を更新します。
さて、質問はあまり明確ではありませんが、おそらく2列を結合したUNIQUE
制約が必要です:(category_id, gallery_id)
。
ALTER TABLE category_gallery
ADD CONSTRAINT category_gallery_uq
UNIQUE (category_id, gallery_id) ;
挿入する行がbothの値と一致し、テーブルにすでに行がある場合、INSERT
の代わりにUPDATE
を実行します。
INSERT INTO category_gallery (
category_id, gallery_id, create_date, create_by_user_id
) VALUES ($1, $2, $3, $4)
ON CONFLICT (category_id, gallery_id)
DO UPDATE SET
last_modified_date = EXCLUDED.create_date,
last_modified_by_user_id = EXCLUDED.create_by_user_id ;
UNIQUE制約のいずれかの列を使用できます。
ON CONFLICT (category_id, gallery_id)
または制約名:
ON CONFLICT ON CONSTRAINT category_gallery_uq
現在受け入れられている答え の簡略化された代替として、テーブルの作成時にUNIQUE
制約を匿名で追加できます。
CREATE TABLE table_name (
id TEXT PRIMARY KEY,
col TEXT,
UNIQUE (id, col)
);
次に、upsertクエリは次のようになります(既に回答されたものと同様)。
INSERT INTO table_name (id, col) VALUES ($1, $2)
ON CONFLICT (id, col)
DO UPDATE SET col = $2;