当冲突发生时,如何使用新值进行更新



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已经可用时,它应该使用主键id通过新值来update该行。当我第一次插入数据时,我不会传递id,因为它的串行类型将自动生成。在这种情况下,我可以将id作为null发送,因为当我试图更新该时间时,需要id字段。

从这个问题可以清楚地看出,您给出的代码并不是您所拥有的确切代码。正如您所描述的,由于您插入时没有传递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所有记录。

最新更新