在关系型数据库中,术语upsert
称为合并:当插入数据时,如果数据已存在则进行更新,否则插入新行。PostgreSQL 使用 INSERT ON CONFLICT
实现这一功能。
语法
目标
:能唯一标识数据的表达式,比如主键、唯一约束等行为
:可以是以下之一:DO NOTHING
:如果数据已存在,则不执行任何操作DO UPDATE SET 字段1=值1, ... WHERE 条件
:更新某些字段的值
示例
示例数据:
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
);
INSERT INTO
customers (name, email)
VALUES
('IBM', '[email protected]'),
('Microsoft', '[email protected]'),
('Intel', '[email protected]');
示例一: 插入“Microsoft”的联系方式
INSERT INTO customers (name, email)
VALUES('Microsoft','[email protected]')
ON CONFLICT ON CONSTRAINT customers_name_key
DO NOTHING;
由于已存在 Microsoft
,并且 ON CONFLICT
的 行为
是 DO NOTHING
,所以不执行使用操作。
本示例的 目标
使用的是唯一约束 CONSTRAINT customers_name_key
,相对的,直接使用唯一约束的字段名会更直观:
示例二:插入/更新“Microsoft”的联系方式
INSERT INTO customers (name, email)
VALUES('Microsoft','[email protected]')
ON CONFLICT (name)
DO
UPDATE SET email = EXCLUDED.email || ';' || customers.email;