如何在postgres 9.5中正确地进行upsert

use*_*921 30 sql postgresql upsert postgresql-9.5

用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`;
Run Code Online (Sandbox Code Playgroud)

我试图改变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中正确进行upsert?

如果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`;
Run Code Online (Sandbox Code Playgroud)

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 | ...
Run Code Online (Sandbox Code Playgroud)

ype*_*eᵀᴹ 54

ON CONFLICT结构需要UNIQUE约束工作.从文章中的INSERT .. ON CONFLICT条款:

optional ON CONFLICT子句指定了引发唯一违规排除约束违规错误的备用操作.对于建议插入的每个单独的行,插入继续进行,或者,如果违反了conflict_target指定的仲裁器约束或索引,则采用替代的conflict_action.ON CONFLICT DO NOTHING只是避免插入行作为替代操作.ON CONFLICT DO UPDATE更新与建议插入的行冲突的现有行作为其替代操作.

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

ALTER TABLE category_gallery
    ADD CONSTRAINT category_gallery_uq
    UNIQUE (category_id, gallery_id) ;
Run Code Online (Sandbox Code Playgroud)

如果要插入的行与表中已有行的两个值匹配,则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 ;
Run Code Online (Sandbox Code Playgroud)

您可以使用UNIQUE约束的列:

  ON CONFLICT (category_id, gallery_id) 
Run Code Online (Sandbox Code Playgroud)

或约束名称:

  ON CONFLICT ON CONSTRAINT category_gallery_uq  
Run Code Online (Sandbox Code Playgroud)


Eri*_*rik 5

作为当前接受的答案的简化替代,UNIQUE可以在创建表时匿名添加约束:

CREATE TABLE table_name (
    id  TEXT PRIMARY KEY,
    col TEXT,
    UNIQUE (id, col)
);
Run Code Online (Sandbox Code Playgroud)

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

INSERT INTO table_name (id, col) VALUES ($1, $2)
ON CONFLICT (id, col)
    DO UPDATE SET col = $2;
Run Code Online (Sandbox Code Playgroud)