原文:http://hi.baidu.com/mawf2008/item/eec8c7ad1c5be5ae29ce9da6
merge into a
using bon (a.a=b.b)when matched then update xxxxxwhen not matched then insert (xxx) values(xxx);oracle使用 merge 更新或插入数据(总结) 总结下。使用merge比传统的先判断再选择插入或更新快很多。1)主要功能提供有条件地更新和插入数据到数据库表中如果该行存在,执行一个UPDATE操作,如果是一个新行,执行INSERT操作— 避免了分开更新— 提高性能并易于使用— 在数据仓库应用中十分有用2)MERGE语句的语法如下:MERGE [hint] INTO [schema .] table [t_alias] USING [schema .]{ table | view | subquery } [t_alias] ON ( condition )WHEN MATCHED THEN merge_update_clauseWHEN NOT MATCHED THEN merge_insert_clause;还是看例子就知道怎么回事:MERGE INTO copy_emp cUSING employees eON (c.employee_id=e.employee_id)WHEN MATCHED THENUPDATE SETc.first_name=e.first_name,c.last_name=e.last_name,c.department_id=e.department_idWHEN NOT MATCHED THENINSERT VALUES(e.employee_id,e.first_name,e.last_name,e.email,e.phone_number,e.hire_date,e.job_id,e.salary,e.commission_pct,e.manager_id,e.departmetn_id);MERGE INTO copy_emp cUSING employees eON (c.employee_id=e.employee_id)WHEN MATCHED THENUPDATE SETc.first_name=e.first_name,c.last_name=e.last_name,c.department_id=e.department_idWHEN NOT MATCHED THENINSERT VALUES(e.employee_id,e.first_name,e.last_name,e.email,e.phone_number,e.hire_date,e.job_id,e.salary,e.commission_pct,e.manager_id,e.departmetn_id);3)使用merge的注意事项:创建测试表:CREATE TABLE MM (ID NUMBER, NAME VARCHAR2(20));CREATE TABLE MN (ID NUMBER, NAME VARCHAR2(20));插入数据INSERT INTO MM VALUES (1, 'A');INSERT INTO MN VALUES (1, 'B');执行:MERGE INTO MN AUSING MM BON(A.ID=B.ID)WHEN MATCHED THENUPDATE SET A.ID = B.IDWHEN NOT MATCHED THENINSERT VALUES(B.ID, B.NAME);ON(A.ID=B.ID)报错:无效的标识符,这个错误提示有些误导嫌疑,原因是on子句的使用的字段不能够用于update,即Oracle不允许更新用于连接 的列修改:MERGE INTO MN AUSING MM BON(A.ID=B.ID)WHEN MATCHED THENUPDATE SET A.NAME = B.NAMEWHEN NOT MATCHED THENINSERT VALUES(B.ID, B.NAME);ON(A.ID=B.ID)再插入:INSERT INTO MM VALUES (1, 'C');再执行:MERGE INTO MN AUSING MM BON(A.ID=B.ID)WHEN MATCHED THENUPDATE SET A.NAME = B.NAMEWHEN NOT MATCHED THENINSERT VALUES(B.ID, B.NAME);ON(A.ID=B.ID)报错,原因无法在源表中获得一组稳定的行4)更新同一张表的数据。需要注意下细节,因为可能涉及到using的数据集为null,所以要使用count()函数。MERGE INTO mn aUSING (select count(*) co from mn where mn.ID=4) bON (b.co<>0)--这里使用了count和<>,注意下,想下为什么!WHEN MATCHED THENUPDATESET a.NAME = 'E'where a.ID=4WHEN NOT MATCHED THENINSERTVALUES (4, 'E');