Postgresql 實現資料不存在插入,存在更新
阿新 • • 發佈:2022-03-18
有時候需要往表裡增量插入資料,此時可能會出現唯一鍵重複而沒法插入的錯誤。尤其是一些儲存過程中經常出現【無則插入,有則更新】的邏輯。PostgreSQL9.5 開始庫提供了Upset方法可以輕鬆實現此邏輯:
語法形式
INSERT INTO 表名 VALUES ('值1', '值2', ...) ON CONFLICT ON CONSTRAINT 唯一或排除約束名 DO UPDATE SET 列1='值', 列2='值', ...; --或 INSERT INTO 表名 VALUES ('值1', '值2', ...) ON CONFLICT(唯一或排除約束欄位名) DO UPDATE SET 列1='值', 列2='值', ...;
示例
--若要從person表往TEST表更新全部記錄,不重複插入,重複則更新
INSERT INTO TEST
select * from person
on conflict on constraint pk_test_deviceid_eventtype do
update set updatetime = excluded.updatetime, msec = excluded.msec;
實踐
create table test(id int constraint idx_t_id primary key,name varchar(20) constraint cst_name not null); --插入測試資料 insert into test values(1,'ALMJ'); insert into test values(2,'Tom'); insert into test values(3,'Cat');
建立一個test表,並給id欄位設定唯一鍵約束。看看此表的約束資訊
select table_name, constraint_name, constraint_type
from information_schema.table_constraints
where table_name='test';
--result
/**
test idx_t_id PRIMARY KEY
test 2200_21059_1_not_null CHECK
test 2200_21059_2_not_null CHECK
**/
更新一條重複id的記錄看
insert into test values(1,'阿力木') ON CONFLICT(id) do update set name=EXCLUDED.name ; --result /*** insert into test values(1,'阿力木') ON CONFLICT(id) do update set name=EXCLUDED.name > Affected rows: 1 > 時間: 0.006s ***/
成功了,或者可能重複的時候不要報錯也不要更新,自動跳過
insert into test values(2,'湯姆'),(3,'凱特') ON CONFLICT(id) do nothing ;
--result
/***
insert into test values(2,'湯姆'),(3,'凱特') ON CONFLICT(id) do nothing
> Affected rows: 0
> 時間: 0s
id name
2 Tom
3 Cat
1 阿力木
***/