關於ORACLE merge into 的兩個常見錯誤

------- MERGE語法簡介
語法以下:
MERGE hint INTO schema . table t_alias
USING schema . { table | view | subquery } t_alias
ON (condition)
WHEN MATCHED THEN merge_update_clause
WHEN NOT MATCHED THEN merge_insert_clause;


--好處:是執行 同時有插入和更新操做時效率最高的腳本
講解前建表:

CREATE TABLE TEST_111111
 (ID NUMBER(18),
 NAME VARCHAR2(255)
 );
 
 INSERT INTO TEST_111111
 VALUES (1,'小紅');
 
 
 INSERT INTO TEST_111111
 VALUES (2,'小紅');
 
 CREATE TABLE TEST_222222
 AS
 SELECT * FROM TEST_111111
 WHERE ID = 1;
數據庫

  Oracle10g中MERGE的完善
在Oracle10g之後,Oracle的MERGE發生了改變
 UPDATE和INSERT動做可只出現其一 
--能夠只出現update 
 MERGE INTO TEST_111111 T1
 USING TEST_222222 T2
 ON (T1.ID = T2.ID)
 WHEN MATCHED THEN
   UPDATE SET T1.NAME = T2.NAME;
--也可選擇僅僅INSERT目標表而不作任何UPDATE動做
 MERGE INTO TEST_111111 T1
 USING TEST_222222 T2
 ON (T1.ID = T2.ID)
 WHEN NOT MATCHED THEN
   INSERT VALUES (T2.ID, T2.NAME);
 
 --而9i 版本的 則update 與 insert  都必須存在
 MERGE INTO TEST_111111 T1
 USING TEST_222222 T2
 ON (T1.ID = T2.ID)
 WHEN MATCHED THEN
   UPDATE SET T1.NAME = T2.NAME
 WHEN NOT MATCHED THEN
   INSERT VALUES (T2.ID, T2.NAME);

-----------兩種最多見的錯誤:spa

-PART1.ora-30926 :沒法在源表中得到一組穩定的行it

INSERT INTO TEST_111111
 VALUES (1,'小紅');io

上面這條語句執行兩次,插入兩條相同的記錄table

INSERT INTO TEST_222222
  SELECT * FROM TEST_111111
 WHERE ID = 1;效率

MERGE INTO TEST_111111 T1
 USING TEST_222222 T2
 ON (T1.NAME = T2.NAME )
 WHEN MATCHED THEN
 UPDATE SET T1.ID = 521
 WHEN NOT MATCHED THEN
 INSERT VALUES (T2.ID,T2.NAME);date

這時候就會報ORA-30926:沒法再源表中得到一組穩定的行語法

緣由 :T1 表爲源表,意思是 在 ON(CONDITION) 這裏在作CONDITION 判斷的時候,匹配到的T1中的數據不止一條,因此CONDITION 這裏建議 以主鍵爲條件,這樣就避免了匹配到多條數據的問題。引用

解決方案:知道了出錯緣由,解決起來就有方向可尋數據

假設 iD爲主鍵,腳本改爲

MERGE INTO TEST_111111 T1
 USING TEST_222222 T2
 ON (T1.ID= T2.ID)
 WHEN MATCHED THEN
 UPDATE SET T1.NAME = T2.NAME
 WHEN NOT MATCHED THEN
 INSERT VALUES (T2.ID,T2.NAME);

--PART2:ora-38104:沒法更新on子句中引用的列

 MERGE INTO TEST_111111 T1
 USING TEST_222222 T2
 ON (T1.NAME = T2.NAME )
 WHEN MATCHED THEN
 UPDATE SET T1.NAME = T2.NAME
 WHEN NOT MATCHED THEN
 INSERT VALUES (T2.ID,T2.NAME);

出錯緣由:這裏在 作ON 判斷時 已經對name 字段進行匹配了,這就比如我在進行一組表更新操做的時候的鎖表狀態,因此想更新NAME 便不能用NAME 作條件判斷。

思考:錯誤二引起對錯誤一的思考

假使我在作ON判斷的時候用的是表的主鍵,而後我想作UPDATE 操做的時候若是是on 裏面的條件字段,也就是說 要更新的是  數據庫 中 表的主鍵 ,這也就違背了  數據庫的主鍵約束條件。所以,從錯誤二去反推錯誤一,就天然好理解了。

相關文章
相關標籤/搜索