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`;

我try 将WHERE gallery_id = $2;改为WHERE category_gallery.gallery_id = $2;,然后显示错误there is no unique or exclusion constraint matching the ON CONFLICT specification,但I don't want to set gallery_id or 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 ($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`;

表(类别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页的文档中:

可选的ON CONFLICT子句指定了引发unique violationexclusion constraint违规错误的替代操作.对于建议插入的每一行,要么继续插入,要么,如果违反了conflict_target指定的仲裁者约束或索引,则采取替代conflict_操作.ON CONFLICT DO NOTHING简单地避免插入一行作为其替代操作.ON CONFLICT DO UPDATE更新与作为替代操作建议插入的行冲突的现有行.

现在,问题还不是很清楚,但你可能需要对两列的组合设置UNIQUE个限制:(category_id, gallery_id).

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

如果要插入的行将both个值与表中已存在的行匹配,则执行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 ;

可以使用唯一约束的任一列:

  ON CONFLICT (category_id, gallery_id) 

或约束名称:

  ON CONFLICT ON CONSTRAINT category_gallery_uq  

Postgresql相关问答推荐

将几个左连接合并为一个

Haskell仆人发布FormUrlEncode for(向量字符串)字段

是否从表中 Select 值?巴什

我应该如何更新热门表?

尽管违反了部分索引约束,Postgres 插入仍在发生

有没有办法共享数据或监控复杂 PostgresQL 事务的进度?

在 PostgreSQL 中 Select 数字命名列会返回 ?column?

在 Ubuntu 11.04 服务器中启用对 postgresql 的 PHP 支持

try 访问本地主机中的数据库时如何解决Error: The server does not support SSL connections?

在执行 postgresql 函数时提交事务

带有初始数据的 docker postgres 不会在提交中持久化

带有 -C 选项的 pg_restore 不会创建数据库

带有双引号的 postgresql COPY 和 CSV 数据

'active' 标志与否?

将属性添加到 Sequelize FindOne 返回的对象

在 postgres 中存在不同的 string_agg 问题

Postgresql 对象 ID 和元组

Postgres DB 上的整数超出范围

PostgreSQL - 如何在不同时区呈现日期?

PostgreSQL:如何解决numeric field overflow问题