1. 程式人生 > 實用技巧 >oracle中對insert into on duplicate key 語句的替代

oracle中對insert into on duplicate key 語句的替代

insert into on duplicate key 是mysql中的語句,oracle中沒有直接對應。不過採用merge into語句可以起到相同效果。

比如有一個表TTT,我們在no,start_time,code三個欄位上建立了唯一索引;希望插入新記錄時,如果在唯一索引上有重複的就更新,沒有就直接插入。

MERGE INTO TTT
USING 
  (select count(*) num from TTT where no = '7099' and start_time = to_date('20200817204243','yyyyMMddHH24miss') and code = '
01060') q ON (q.num=1) WHEN MATCHED THEN update set end_time = to_date('20200817210000','yyyyMMddHH24miss'), state = 1 where no = '7099' and start_time = to_date('20200817204243','yyyyMMddHH24miss') and code = '01060' WHEN NOT MATCHED THEN insert (id, no, sec, stor_time, o_time, start_time, end_time, state, frs, code)
values('5', '7099', '1', TO_DATE('2020-08-17 20:52:32', 'SYYYY-MM-DD HH24:MI:SS'), TO_DATE('2020-08-17 20:52:32', 'SYYYY-MM-DD HH24:MI:SS'), TO_DATE('2020-08-17 22:31:31', 'SYYYY-MM-DD HH24:MI:SS'), TO_DATE('2020-08-17 22:31:50', 'SYYYY-MM-DD HH24:MI:SS'),'0','145','01200');

後經人指點,發現可以改成下面這樣,效率提高:

MERGE INTO
TTT USING dual ON (no = '7099' and start_time = to_date('20200817204243','yyyyMMddHH24miss') and code = '01060') WHEN MATCHED THEN update set end_time = to_date('20200817210000','yyyyMMddHH24miss'), state = 1 where no = '7099' and start_time = to_date('20200817204243','yyyyMMddHH24miss') and code = '01060' WHEN NOT MATCHED THEN insert (id, no, sec, stor_time, o_time, start_time, end_time, state, frs, code) values('5', '7099', '1', TO_DATE('2020-08-17 20:52:32', 'SYYYY-MM-DD HH24:MI:SS'), TO_DATE('2020-08-17 20:52:32', 'SYYYY-MM-DD HH24:MI:SS'), TO_DATE('2020-08-17 22:31:31', 'SYYYY-MM-DD HH24:MI:SS'), TO_DATE('2020-08-17 22:31:50', 'SYYYY-MM-DD HH24:MI:SS'),'0','145','01200');

新語句使用了dual表;避免了count(*)操作。實際上insert部分和條件之間沒有什麼直接關聯,應該由外部程式(比如JDBC中的PreparedStatement設定引數時)來保持一致。