insert into t --進行插入 values(1,'name') ON CONFLICT(id) --如果id這個鍵存在 do update set --更新以下字段 name=EXCLUDED.name ; insert into t (a1,b1,c1) select a2,b2,c2 from t2 on conflict(a1) do update set (b1,c1) = (1,2)
conflict里的字段必須為主鍵或者唯一索引,可以多個字段作為唯一索引,在數據庫設置唯一,不然會報
"there is no unique or exclusion constraint matching the ON CONFLICT specification"錯誤
批量查詢插入的時候想到了update時再按上面selete查詢一遍應該就能自動全插進去了吧,然而現實總是殘酷的
insert into t (a1,b1,c1) select a2,b2,c2 from t2 on conflict(a1) do update set (b1,c1)= (select a2,b2,c2 from t2)
報錯:"more than one row returned by a subquery used as an expression"
這樣的查詢 do update set只能設置一條數據
插入和更新並不是批量數據一一對應操作的 而是批量insert然后再判斷是否更新 所以下面只能寫死一條數據 多了就報錯..遂百度
發現pgsql在這種情況下會提供一個EXCLUDED臨時表把之前插入的值儲存起來,然后就可以
insert into t (a1,b1,c1)--進行插入操作 select a2,b2,c2 from t2 on conflict(a1) --如果存在a1 do update set --進行下面字段更新 (b1,c1) = (EXCLUDED.b1,EXCLUDED.c1)
這樣就能實現批量查詢插入或更新了
INSERT INTO "DeptApportionParams" ( "HD_No", "HD_Name", "HD_Type", "DAP_Year", "DAP_Month" ) (SELECT "HD_No", "HD_Name", "HD_Type", 2020, 2 FROM "Hosp_Dept" WHERE "HD_No"='235060570540347400' OR "HD_No"='235060570540347393' --"HD_No"='235060570540347400' --OR "HD_No"='235060570540347393' ) ON conflict ON CONSTRAINT "pr_DAP_Key" DO UPDATE SET ("HD_No","HD_Name","HD_Type") =(EXCLUDED."HD_No",EXCLUDED."HD_Name",EXCLUDED."HD_Type")
where
"HD_No" is DISTINCT FROM EXCLUDED."HD_No" OR
"HD_Name" is DISTINCT FROM EXCLUDED."HD_Name" OR
"HD_Type" is DISTINCT FROM EXCLUDED."HD_Type"
感謝 :
PgSQL upsert批量查詢插入或更新(insert select/on conflict do update踩坑記錄)
如果希望不同就更新怎么處理?
is DISTINCT FROM功能描述
A和B的數據類型、值不完全相同返回 true
A和B的數據類型、值完全相同返回 false
將空值視為相同。