近期有一个需求,向一张数据库表插入数据,如果是新数据则执行插入动作,如果插入的字段和已有字段重复,则更新该行对应的部分字段
1. 创建测试表
create table meta_data ( id serial, user_id varchar(128) DEFAULT NULL, file_name varchar(1024) DEFAULT NULL, file_path varchar(1024) DEFAULT NULL, update_time TIMESTAMP DEFAULT NULL, UNIQUE (user_id,file_name) ); postgres=# \d meta_data Table "public.meta_data" Column | Type | Modifiers -------------+-----------------------------+-------------------------------------------------------- id | integer | not null default nextval('meta_data_id_seq'::regclass) user_id | character varying(128) | default NULL::character varying file_name | character varying(1024) | default NULL::character varying file_path | character varying(1024) | default NULL::character varying update_time | timestamp without time zone | Indexes: "meta_data_user_id_file_name_key" UNIQUE CONSTRAINT, btree (user_id, file_name)
2. 插入两条测试数据
INSERT INTO meta_data ( user_id, file_name, file_path, UPDATE_TIME ) VALUES ( 'user_id01', 'file_name01', '/usr/local/file_name01', now()) ON CONFLICT (user_id, file_name) DO UPDATE SET file_path = EXCLUDED.file_path, UPDATE_TIME = EXCLUDED.UPDATE_TIME; INSERT INTO meta_data ( user_id, file_name, file_path, UPDATE_TIME ) VALUES ( 'user_id02', 'file_name02', '/usr/local/file_name02', now()) ON CONFLICT (user_id, file_name) DO UPDATE SET file_path = EXCLUDED.file_path, UPDATE_TIME = EXCLUDED.UPDATE_TIME;
postgres=# select * from meta_data; id | user_id | file_name | file_path | update_time ----+-----------+-------------+------------------------+---------------------------- 1 | user_id01 | file_name01 | /usr/local/file_name01 | 2019-09-23 17:14:52.39878 2 | user_id02 | file_name02 | /usr/local/file_name02 | 2019-09-23 17:14:53.118192 (2 rows)
3. 插入第三条测试数据,注意插入的字段user_id和file_name和第二条语句对应的字段是重复的
INSERT INTO meta_data ( user_id, file_name, file_path, UPDATE_TIME ) VALUES ( 'user_id02', 'file_name02', '/usr/local/file_name03', now()) ON CONFLICT (user_id, file_name) DO UPDATE SET file_path = EXCLUDED.file_path, UPDATE_TIME = EXCLUDED.UPDATE_TIME;
postgres=# select * from meta_data; id | user_id | file_name | file_path | update_time ----+-----------+-------------+------------------------+---------------------------- 1 | user_id01 | file_name01 | /usr/local/file_name01 | 2019-09-23 17:14:52.39878 2 | user_id02 | file_name02 | /usr/local/file_name03 | 2019-09-23 17:16:52.457696 (2 rows)
可以看到新插入的第三条语句其实是更新了已存在的第二条记录