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
);
请注意,name
是unique
,因此,如果insert
尝试添加具有已存在的name
的记录,则该命令位于具有该记录的conflict
中,并且该命令将被更新。如果您不提供id
,那么您的命令将不会有任何冲突,并且不会更新,而是insert
所有记录。