ORACLE MERGE INTO UPDATE DELETE 用法


ORACLE MERGE INTO UPDATE DELETE 用法

 

使用該MERGE語句從一個或多個源中選擇行以進行更新或插入表或視圖。您可以指定條件以確定是更新還是插入目標表或視圖。

此語句是組合多個操作的便捷方式。它可以讓你避免多次INSERTUPDATEDELETEDML語句。MERGE是一個確定性的陳述。您無法在同一MERGE語句中多次更新目標表的同一行。

 

1.1先決條件

您必須具有INSERTUPDATE目標表和對象的權限READSELECT源表上的對象權限。要指定DELETE子句merge_update_clause,還必須DELETE在目標表上具有對象特權。

1.2句法

merge :: =

 

 

 

注意:您必須至少指定其中一個條款merge_update_clausemerge_insert_clause

merge_update_clause :: =

 

 

merge_insert_clause :: =

 

 

where_clause :: =

 

 

error_logging_clause :: =

 

 

 

1.3關於INTO 說明

使用該INTO子句指定要更新或插入的目標表或視圖。為了將數據合並到視圖中,視圖必須是可更新的。

 

對目標視圖的限制

您無法指定INSTEAD OF已定義觸發器的目標視圖。

 

1.4關於ON 說明

使用該ON子句指定MERGE操作更新或插入的條件。對於搜索條件為true的目標表中的每一行,Oracle數據庫使用源表中的相應數據更新該行。如果任何行的條件不為真,則數據庫將根據相應的源表行插入目標表。

 

ON條款的限制

在以前版本的Oracle數據庫中,當您在包含該MERGE INTO語句的應用程序上創建Oracle虛擬專用數據庫策略時,由於存在虛擬專用數據庫策略,該MERGE INTO語句將被阻止並出現ORA-28132: Merge into syntax does not support security policies錯誤。從Oracle Database 11g211.2.0.2)開始,您可以在包含MERGE INTO操作的應用程序上創建策略。要做到這一點,在DBMS_RLSADD_POLICY statement_types參數,包括INSERTUPDATE,和DELETE語句,或只是省略statement_types參數完全。有關對特定SQL語句類型實施策略的詳細信息,請參閱“ Oracle數據庫安全指南

 

1.5     merge_update_clause

merge_update_clause指定目標表的新列值。如果ON子句的條件為真,Oracle將執行此更新。如果執行update子句,則激活目標表上定義的所有更新觸發器。

指定where_clause,如果你想在數據庫中執行僅當指定條件為真更新操作。條件可以指數據源或目標表。如果條件不為true,則數據庫會在將行合並到表中時跳過更新操作。

指定DELETE where_clause填充或更新表時清理表中的數據。受此子句影響的唯一行是目標表中由合並操作更新的那些行。該DELETE WHERE條件對更新后的值,而不是由評估原值UPDATE SET... WHERE條件。如果目標表的一行符合DELETE條件但未包含在ON子句定義的連接中,則不會刪除它。對於每行刪除,將激活目標表上定義的任何刪除觸發器。

您可以單獨指定此子句,也可以使用merge_insert_clause。如果同時指定兩者,則它們可以按任意順序排列

: delele 只能跟update 一起使用,同時where只能出現一次,如果update 使用了wheredelete后面的where就無效了。

 

merge_update_clause限制

本條款受以下限制:

  • 您無法更新ON condition子句中引用的列。
  • 您無法在更新視圖時指定DEFAULT

1.6     merge_insert_clause

merge_insert_clause指定的值以插入到目標表的列,如果條件ON子句是假的。如果執行insert子句,則激活目標表上定義的所有插入觸發器。如果省略INSERT關鍵字后面的列列表,則目標表中的列數必須與VALUES子句中的值數相匹配。

要將所有源行插入表中,可以在子句條件中使用常量過濾謂詞ON。常量過濾謂詞的一個例子是ON0=1)。Oracle數據庫識別這樣的謂詞,並將所有源行無條件地插入到表中。這種方法不同於省略merge_update_clause。在這種情況下,數據庫仍然必須執行連接。使用常量過濾器謂詞,不執行任何連接。

指定where_clause,如果你想Oracle數據庫執行插入操作僅當指定條件為真。條件只能引用數據源表。Oracle數據庫會跳過條件不為真的所有行的插入操作。

您可以單獨指定此子句,也可以使用merge_update_clause。如果同時指定兩者,則它們可以按任意順序排列。

merge_insert_clause限制

DEFAULT插入視圖時無法指定。

 

1.7MERGE 示例

1.7.1示例一

以下示例使用bonuses示例模式中的表,oe默認獎勵為100.然后bonuses,根據表的sales_rep_id列,將所有進行銷售的員工插入到oe.orders表中。最后,人力資源經理決定薪水為8000美元或更低的員工應該獲得獎金。那些沒有進行銷售的人可以獲得1%的工資獎金。那些已經進行銷售的人的獎金增加相當於他們工資的1%。該MERGE語句只需一步即可實現這些更改:

CREATE TABLE bonuses (employee_id NUMBER, bonus NUMBER DEFAULT 100);

 

INSERT INTO bonuses(employee_id)

   (SELECT e.employee_id FROM employees e, orders o

   WHERE e.employee_id = o.sales_rep_id

   GROUP BY e.employee_id);

 

SELECT * FROM bonuses ORDER BY employee_id;

 

EMPLOYEE_ID      BONUS

----------- ----------

        153        100

        154        100

        155        100

        156        100

        158        100

        159        100

        160        100

        161        100

        163        100

 

MERGE INTO bonuses D

   USING (SELECT employee_id, salary, department_id FROM employees

   WHERE department_id = 80) S

   ON (D.employee_id = S.employee_id)

   WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01

     DELETE WHERE (S.salary > 8000)

   WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus)

     VALUES (S.employee_id, S.salary*.01)

     WHERE (S.salary <= 8000);

 

SELECT * FROM bonuses ORDER BY employee_id;

 

EMPLOYEE_ID      BONUS

----------- ----------

        153        180

        154        175

        155170

        159        180

        160        175

        161        170

        164         72

        165         68

        166         64

        167         62

        171         74

        172         73

        173         61

        179         62

 

參考:https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/MERGE.html#GUID-5692CCB7-24D9-4C0E-81A7-A22436DC968F

1.7.2示例二

目標:從T_TAR表中刪除ID T_ORG表中存在的記錄,將IDT_ORG中存在,而在T_TAR 中不存在,且TPYE類型為TABLE的記錄插入到T_TAR表中。

 

環境建立:

Create table T_ORG (ID NUMBER ,NAME VARCHAR2(30), TYPE VARCHAR2(19));

Create table T_TAR (ID NUMBER ,NAME VARCHAR2(30), TYPE VARCHAR2(19));

INSERT INTO T_ORG SELECT ROWNUM, OBJECT_NAME ,OBJECT_TYPE FROM ALL_OBJECTS;

INSERT INTO T_TAR SELECT * FROM T_ORG WHERE TYPE=’INDEX’;

COMMIT;

 

 

Set timing on

Set autot on

Set linesize 160

alter system flush buffer_cache;

alter system flush shared_pool;

truncate table T_TAR;

truncate table T_ORG;

 

TRUNCATE TABLE T_ORG;

TRUNCATE TABLE T_TAR ;

INSERT INTO T_ORG SELECT ROWNUM, OBJECT_NAME ,OBJECT_TYPE FROM ALL_OBJECTS;

INSERT INTO T_TAR SELECT * FROM T_ORG WHERE TYPE='INDEX';

commit ;

      

MERGE INTO T_TAR t

      USING T_ORG O

        ON (t.id=o.id)   

   WHEN MATCHED THEN  

       updateset t.name = t.name

          DELETE WHERE (t.id=o.id)

   WHEN NOT MATCHED THEN

   INSERTvalues (o.id,o.name,o.type) WHERE (o.type='TABLE') ;

 

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">






免責聲明!

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



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