在oracle中使用merge into實現更新和插入數據


oracle中使用merge into

DUAL表解釋

  • 在Oracle數據庫中,dual是Oracle中的一個偽表,在Oracle數據庫中的select語句的語法為:

    SELECT column_1,  column_2, ...  FROM  table_name;
    

    即在使用select語句時,如果沒有表名,就沒辦法執行查詢,而當我們想查看當前時間sysdate或者想計算出一個表達式例如2+3的值的時候,如果沒有表是無法執行操作的,故Oracle數據庫出現了偽表dual的概念。

    --查詢當前時間,如果后面不跟表,則無法查詢,例如
    SELECT sysdate ;
    --正確寫法
    SELECT sysdate FROM daul;
    
  • 特點:

    • dual名詞意思是對數,做形容詞時是指二重的,二元的。
    • 它是一個單行單列的虛擬表。
    • Dual表是oracle與數據字典一起自動創建的一個表,這個表只有1列:DUMMY,數據類型為VERCHAR2(1),dual表中只有一個數據'X', Oracle有內部邏輯保證dual表中永遠只有一條數據。
    • Dual表主要用來選擇系統變量或求一個表達式的值。
  • 總結:dual表就是oracle與數據字典自動創建的一張表,這張表是一個單行單列的表,這個表只有1列:DUMMY,數據類型為VERCHAR2(1),dual表中只有一個數據'X', Oracle有內部邏輯保證dual表中永遠只有一條數據。dual表主要是用來選擇系統變量或是求一個表達式的值。

使用場景

  • 對數據庫操作時,會存在這樣的需求:insert 或者 Update;
  • 根據某一個條件(比如唯一索引,唯一主鍵等)查詢數據庫,如果數據庫中存在該條數據,則更新,沒有的話就將這條數據插入到數據庫中。
  • 傳統用法:插入之前先select,根據結果來進行update或者insert;
  • 現在:使用MERGE 命令使用一條語句從一個或者多個數據源中完成對表的更新和插入數據。

用法

單表

  • 現有測試表Student下有屬性sid、name、grade等。傳入數據('1001','張三','95')。要求如果存在學號sid為'1001'的學生,則更新他的成績,沒有的話就插入到數據庫中。
MERGE INTO  Student S1
USING (SELECT '1001' as sid,'張三' as name,'95' as grade FROM dual) S2 
on (S1.sid=S2.sid)
WHEN MATCHED THEN 
UPDATE SET S1.name=S2.name,S1.grade=S2.grade
WHEN NOT MATCHED THEN  
INSERT 
(S1.sid, S1.name,S1.grade) 
VALUES 
(S2.sid, S2.name,S2.grade );
--具體解釋
--USING 這里是我們需要跟數據庫進行比較的數據,這里傳入的數據為('1001','張三','95'),為了保證USING后面的select有數據,在這里使用了dual表。
--on后面是我們要比較的條件
--WHEN MATCHED THEN 當存在學號為‘1001’這樣的數據時,選擇將數據庫中的這條數據更新
--WHEN NOT MATCHED THEN  當不存在這條數據時,將這條數據插入到數據庫中。
  • 原理:在使用using 時搜出來的結果逐條與on條件匹配,然后決定是update還是Insert。 當USING后面的sql沒有查詢到數據的時候,Merge Into語句是不會執行update和Insert操作的。因此需要保證USING 后面的SELECT有數據,可以使用DUAL表作為USING后的表。

  • 注意點:在實際項目中,using表后邊傳入的數據,可以是前台傳過來的對象,例如前台傳過來Student(SID:'1001',NAME:'張三',GRADE:'95');這是可以這樣:

    MERGE INTO  Student S1
    USING (SELECT #{SID,jdbcType=VARCHAR} sid FROM dual) S2 
    on (S1.sid=S2.sid)
    WHEN MATCHED THEN 
    UPDATE SET S1.name= #{NAME,jdbcType=VARCHAR},S1.grade=#{GRADE,jdbcType=VARCHAR}
    WHEN NOT MATCHED THEN  
    INSERT 
    sid,name,grade) 
    VALUES 
    (#{SID,jdbcType=VARCHAR} #{NAME,jdbcType=VARCHAR},#{GRADE,jdbcType=VARCHAR})
    --mabatis最后語句不能以‘;’結尾,否則會報 ‘無效字符’ 錯誤。
    

多表

  • 使用多張表時,比如A 表中的id對應與B表中的aid,只需在USING中使用select語句時的FROM表改為B表即可,其他的使用方法類似。

原創不易,歡迎轉載,轉載時請注明出處,謝謝!
作者:瀟~蕭下
原文鏈接:https://www.cnblogs.com/manongxiao/p/12241833.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM