天天看點

oracle merge的用法

MERGE語句是Oracle9i新增的文法,用來合并UPDATE和INSERT語句。

  通過MERGE語句,根據一張表或子查詢的連接配接條件對另外一張表進行查詢,

  連接配接條件比對上的進行UPDATE,無法比對的執行INSERT。

  這個文法僅需要一次全表掃描就完成了全部工作,執行效率要高于INSERT+UPDATE。

文法

MERGE [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;      

1、UPDATE或INSERT子句是可選的

2、UPDATE和INSERT子句可以加WHERE子句

3、在ON條件中使用常量過濾謂詞來insert所有的行到目标表中,不需要連接配接源表和目标表

4、UPDATE子句後面可以跟DELETE子句來去除一些不需要的行

首先建立示例表: 

create table PRODUCTS 
      ( 
      PRODUCT_ID INTEGER, 
      PRODUCT_NAME VARCHAR2(60), 
      CATEGORY VARCHAR2(60) 
      ); 

      insert into PRODUCTS values (1501, 'VIVITAR 35MM', 'ELECTRNCS'); 
      insert into PRODUCTS values (1502, 'OLYMPUS IS50', 'ELECTRNCS'); 
      insert into PRODUCTS values (1600, 'PLAY GYM', 'TOYS'); 
      insert into PRODUCTS values (1601, 'LAMAZE', 'TOYS'); 
      insert into PRODUCTS values (1666, 'HARRY POTTER', 'DVD'); 
      commit;      
create table NEWPRODUCTS 
      ( 
      PRODUCT_ID INTEGER, 
      PRODUCT_NAME VARCHAR2(60), 
      CATEGORY VARCHAR2(60) 
      ); 

      insert into NEWPRODUCTS values (1502, 'OLYMPUS CAMERA', 'ELECTRNCS'); 
      insert into NEWPRODUCTS values (1601, 'LAMAZE', 'TOYS'); 
      insert into NEWPRODUCTS values (1666, 'HARRY POTTER', 'TOYS'); 
      insert into NEWPRODUCTS values (1700, 'WAIT INTERFACE', 'BOOKS'); 
      commit;      

1、可省略的UPDATE或INSERT子句

在Oracle 9i, MERGE語句要求你必須同時指定INSERT和UPDATE子句.而在Oracle 10g, 你可以省略UPDATE或INSERT子句中的一個. 下面的例子根據表NEWPRODUCTS的PRODUCT_ID字段是否比對來updates表PRODUCTS的資訊: 

SQL> MERGE INTO products p 
      2 USING newproducts np 
      3 ON (p.product_id = np.product_id) 
      4 WHEN MATCHED THEN 
      5 UPDATE 
      6 SET p.product_name = np.product_name, 
      7 p.category = np.category; 

      3 rows merged.      
SQL> SELECT * FROM products; 

      PRODUCT_ID PRODUCT_NAME CATEGORY 
      ---------- -------------------- ---------- 
      1501 VIVITAR 35MM ELECTRNCS 
      1502 OLYMPUS CAMERA ELECTRNCS 
      1600 PLAY GYM TOYS 
      1601 LAMAZE TOYS 
      1666 HARRY POTTER TOYS 
      SQL> 
      SQL> ROLLBACK; 
      Rollback complete. 
      SQL>      

在上面例子中, MERGE語句影響到是産品id為1502, 1601和1666的行. 它們的産品名字和種 類被更新為表newproducts中的值. 下面例子省略UPDATE子句, 把表NEWPRODUCTS中新的PRODUCT_ID插入到表PRODUCTS中, 對于在兩個表中能夠比對上PRODUCT_ID的資料不作任何處理. 從這個例子你能看到PRODUCT_ID=1700的行被插入到表PRODUCTS中. 

SQL> MERGE INTO products p 
      2 USING newproducts np 
      3 ON (p.product_id = np.product_id) 
      4 WHEN NOT MATCHED THEN 
      5 INSERT 
      6 VALUES (np.product_id, np.product_name, 
      7 np.category); 

      1 row merged.      
SQL> SELECT * FROM products; 

      PRODUCT_ID PRODUCT_NAME CATEGORY 
      ---------- -------------------- ---------- 
      1501 VIVITAR 35MM ELECTRNCS 
      1502 OLYMPUS IS50 ELECTRNCS 
      1600 PLAY GYM TOYS 
      1601 LAMAZE TOYS 
      1666 HARRY POTTER DVD 
      1700 WAIT INTERFACE BOOKS      

     2、帶條件的Updates和Inserts子句

你能夠添加WHERE子句到UPDATE或INSERT子句中去, 來跳過update或insert操作對某些行的處理. 下面例子根據表NEWPRODUCTS來更新表PRODUCTS資料, 但必須字段CATEGORY也得同時比對上: 

SQL> MERGE INTO products p 
      2 USING newproducts np 
      3 ON (p.product_id = np.product_id) 
      4 WHEN MATCHED THEN 
      5 UPDATE 
      6 SET p.product_name = np.product_name 
      7 WHERE p.category = np.category; 

      2 rows merged.      
SQL> SELECT * FROM products; 

      PRODUCT_ID PRODUCT_NAME CATEGORY 
      ---------- -------------------- ---------- 
      1501 VIVITAR 35MM ELECTRNCS 
      1502 OLYMPUS CAMERA ELECTRNCS 
      1600 PLAY GYM TOYS 
      1601 LAMAZE TOYS 
      1666 HARRY POTTER DVD 
      SQL> 
      SQL> rollback      

在這個例子中, 産品ID為1502,1601和1666比對ON條件但是1666的category不比對. 是以MERGE指令隻更新兩行資料. 下面例子展示了在Updates和Inserts子句都使用WHERE子句: 

SQL> MERGE INTO products p 
      2 USING newproducts np 
      3 ON (p.product_id = np.product_id) 
      4 WHEN MATCHED THEN 
      5 UPDATE 
      6 SET p.product_name = np.product_name, 
      7 p.category = np.category 
      8 WHERE p.category = 'DVD' 
      9 WHEN NOT MATCHED THEN 
      10 INSERT 
      11 VALUES (np.product_id, np.product_name, np.category) 
      12 WHERE np.category != 'BOOKS' 
      SQL> / 

      1 row merged.      
SQL> SELECT * FROM products; 

      PRODUCT_ID PRODUCT_NAME CATEGORY 
      ---------- -------------------- ---------- 
      1501 VIVITAR 35MM ELECTRNCS 
      1502 OLYMPUS IS50 ELECTRNCS 
      1600 PLAY GYM TOYS 
      1601 LAMAZE TOYS 
      1666 HARRY POTTER TOYS 

      SQL>      

注意由于有WHERE子句INSERT沒有插入所有不比對ON條件的行到表PRODUCTS.

3、無條件的Inserts

你能夠不用連接配接源表和目标表就把源表的資料插入到目标表中. 這對于你想插入所有行到目标表時是非常有用的. Oracle 10g現在支援在ON條件中使用常量過濾謂詞. 舉個常量過濾謂詞例子ON (1=0). 下面例子從源表插入行到表PRODUCTS, 不檢查這些行是否在表PRODUCTS中存在: 

SQL> MERGE INTO products p 
      2 USING newproducts np 
      3 ON (1=0) 
      4 WHEN NOT MATCHED THEN 
      5 INSERT 
      6 VALUES (np.product_id, np.product_name, np.category) 
        SQL> / 

      1 row merged.      
SQL> SELECT * FROM products; 

      PRODUCT_ID PRODUCT_NAME CATEGORY 
      ---------- -------------------- ---------- 
      1501 VIVITAR 35MM ELECTRNCS 
      1502 OLYMPUS IS50 ELECTRNCS 
      1600 PLAY GYM TOYS 
      1601 LAMAZE TOYS 
      1666 HARRY POTTER DVD 
      1700 WAIT INTERFACE BOOKS 
      6 rows selected. 
      SQL>      

4、新增加的DELETE子句

Oracle 10g中的MERGE提供了在執行資料操作時清除行的選項. 你能夠在WHEN MATCHED THEN UPDATE子句中包含DELETE子句. DELETE子句必須有一個WHERE條件來删除比對某些條件的行.比對DELETE WHERE條件但不比對ON條件的行不會被從表中删除.

下面例子驗證DELETE子句. 我們從表NEWPRODUCTS中合并行到表PRODUCTS中, 但删除category為ELECTRNCS的行. 

SQL> MERGE INTO products p 
      2 USING newproducts np 
      3 ON (p.product_id = np.product_id) 
      4 WHEN MATCHED THEN 
      5 UPDATE 
      6 SET p.product_name = np.product_name, 
      7 p.category = np.category 
      8 DELETE WHERE (p.category = 'ELECTRNCS') 
      9 WHEN NOT MATCHED THEN 
      10 INSERT 
      11 VALUES (np.product_id, np.product_name, np.category)      
SQL> / 
      4 rows merged. 
      SQL> SELECT * FROM products; 
      PRODUCT_ID PRODUCT_NAME CATEGORY 
      ---------- -------------------- ---------- 
      1501 VIVITAR 35MM ELECTRNCS 
      1600 PLAY GYM TOYS 
      1601 LAMAZE TOYS 
      1666 HARRY POTTER TOYS 
      1700 WAIT INTERFACE BOOKS 
      SQL>