【问题标题】:how to do update with new value when conflict occures发生冲突时如何使用新值进行更新
【发布时间】:2021-06-03 09:54:30
【问题描述】:

create table new(id serial pk ,name varchar (10),age int)

id 是自动生成的。

insert into new (id,name,age)values(1,' xyz ',21)on conflict(id) do update set name=new_name,age=new_age

id 已经可用时,它应该update 使用主键ID 按新值排列该行。当我第一次插入数据时,我没有传递id,因为它的串行类型会自动生成。在这种情况下,我可以将id 发送为null,因为当我尝试更新该时间时,id 字段是必需的。

【问题讨论】:

    标签: stored-procedures postgresql-9.5 stored-functions


    【解决方案1】:

    从问题中可以清楚地看出,您提供的代码不是您拥有的确切代码。正如您所描述的,由于您在没有传递id 的情况下插入,因此您的实际代码大概如下所示:

    insert into yourtable(name, age)
    values(' xyz ', 21)
    on conflict(id) do
    update set name='new_name',age='new_age';
    

    由于您没有传递id,因此您将永远不会有conflict,因此将插入所有内容。为了处理conflict,您需要了解id 并执行以下操作:

    insert into yourtable(id, name, age)
    values(1, ' xyz ', 21)
    on conflict(id) do
    update set name='new_name',age='new_age';
    

    很明显,您不一定知道记录的 id 是什么,但这是一个算法问题。您需要找出id 是什么。

    请看https://www.postgresqltutorial.com/postgresql-upsert/

    它有一个例子:

    INSERT INTO customers (name, email)
    VALUES('Microsoft','hotline@microsoft.com') 
    ON CONFLICT (name) 
    DO 
       UPDATE SET email = EXCLUDED.email || ';' || customers.email;
    

    表定义为

    DROP TABLE IF EXISTS customers;
    
    CREATE TABLE customers (
        customer_id serial PRIMARY KEY,
        name VARCHAR UNIQUE,
        email VARCHAR NOT NULL,
        active bool NOT NULL DEFAULT TRUE
    );
    

    请注意nameunique,因此,如果insert 尝试添加已存在name 的记录,则该命令在conflict 中与该记录一起,这将是更新。如果您不提供id,那么您的命令将不会有任何冲突并且不会更新,而是insert 所有记录。

    【讨论】:

      猜你喜欢
      • 2010-09-07
      • 2021-08-22
      • 2020-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-20
      • 2014-04-24
      • 1970-01-01
      相关资源
      最近更新 更多