如何在 postgres 9.5 中正确执行 upsert

How to correctly do upsert in postgres 9.5

upsert 与 postgresql 9.5 的正确语法,下面的查询显示 column reference "gallery_id" is ambiguous 错误,为什么?

var dbQuery = `INSERT INTO category_gallery (
  category_id, gallery_id, create_date, create_by_user_id
  ) VALUES (, , , )
  ON CONFLICT (category_id)
  DO UPDATE SET
  category_id = ,
  last_modified_date = ,
  last_modified_by_user_id = 
  WHERE gallery_id = `;

我尝试将 WHERE gallery_id = ; 更改为 WHERE category_gallery.gallery_id = ; 然后显示错误 there is no unique or exclusion constraint matching the ON CONFLICT specification,但是 我不想设置 gallery_id 或 category_id as unique 因为我想确保两列相同然后进行更新....

如何在 postgres 9.5 中正确执行 upsert?

如果 ON CONFLICT 需要唯一列,我应该使用其他方法吗?如何?



我想确定多个列都冲突然后做更新,什么是正确的用法

var dbQuery = `INSERT INTO category_gallery (
  category_id, gallery_id, create_date, create_by_user_id
  ) VALUES (, , , )
  ON CONFLICT (category_id, gallery_id)
  DO UPDATE SET
  category_id = ,
  last_modified_date = ,
  last_modified_by_user_id = 
  WHERE gallery_id = `;


var dbQuery = `INSERT INTO category_gallery (
  category_id, gallery_id, create_date, create_by_user_id
  ) VALUES (, , , )
  ON CONFLICT (category_id AND gallery_id)
  DO UPDATE SET
  category_id = ,
  last_modified_date = ,
  last_modified_by_user_id = 
  WHERE gallery_id = `;

table(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 clause 的文档:

The optional ON CONFLICT clause specifies an alternative action to raising a unique violation or exclusion constraint violation error. For each individual row proposed for insertion, either the insertion proceeds, or, if an arbiter constraint or index specified by conflict_target is violated, the alternative conflict_action is taken. ON CONFLICT DO NOTHING simply avoids inserting a row as its alternative action. ON CONFLICT DO UPDATE updates the existing row that conflicts with the row proposed for insertion as its alternative action.

现在,问题不是很清楚,但您可能需要对 2 列组合的 UNIQUE 约束:(category_id, gallery_id).

ALTER TABLE category_gallery
    ADD CONSTRAINT category_gallery_uq
    UNIQUE (category_id, gallery_id) ;

如果要插入的行与 两个 值匹配,并且 table 上已有一行,则执行 [=23] 而不是 INSERT =]:

INSERT INTO category_gallery (
  category_id, gallery_id, create_date, create_by_user_id
  ) VALUES (, , , )
  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  

作为 的简化替代方案,可以在创建 table:

时匿名添加 UNIQUE 约束
CREATE TABLE table_name (
    id  TEXT PRIMARY KEY,
    col TEXT,
    UNIQUE (id, col)
);

然后,upsert 查询变为(类似于已经回答的内容):

INSERT INTO table_name (id, col) VALUES (, )
ON CONFLICT (id, col)
    DO UPDATE SET col = ;