MERGE 作用与语法
把数据从一个表复制到另一个表,插入新数据或替换掉老数据是每一个 DBA 都会经常碰到的问题。简单地说 Merge 的作用就是:存在就修改或者删除,不存在则插入。
语法:
MERGE INTO table_name table_alias
USING (table|view|sub_query) alias
ON (join condition)
WHEN MATCHED THEN
UPDATE SET
col1 = col1_val,
col2 = col2_val
WHEN NOT MATCHED THEN
INSERT (column_list)
VALUES (column_values);
范例
源表:
SQL> select * from emp_change;
ID SALARY
---------- ----------
7 8500
5 8000
3 1000
6 9000
目标表:
SQL> select * from emp;
ID SALARY
---------- ----------
1 5000
2 6000
3 4000
4 7000
5 5500
现使用源表更新目标表:
merge into emp
using emp_change
on (emp_change.id = emp.id)
when matched then
update set
emp.salary=emp_change.salary
where emp.id=3
delete where (emp.id=5)
when not matched then
insert values(emp_change.id,emp_change.salary)
where emp_change.id=6;
分析:
id = 3,5 能匹配上,如果没有 where emp.id=3,则两条记录都更新,此处只更新 id=3 的行。
id = 6,7 不能匹配上,如果没有 emp_change.id=6,则两记录都插入,此处只插入 emp_change.id=6 的行。
delete 语句不会生效,因为 emp.id = 5 匹配不上 ON 和 update 的 where 条件。
delete where (emp.id=5) 必须放在 where emp.id=3 的后面。
注意事项:
要把 A 表中的数据更新到 B 表中,则 A 为源表, B 为目标表。
1、UPDATE 或 INSERT 动作可只出现其一(9i要求必须同时出现);
2、UPDATE 和 INSERT 子句可以加 WHERE 子句;
3、ON 条件中使用常量过滤谓词(on (1=2))来 insert 所有的行到目标表中,此时不需要对源表和目标表做连接;
4、10g 后加入了 delete 语句,UPDATE 子句后面可以跟 DELETE 子句来去除一些不需要的行,这个语句必须在匹配条件下出现,它是一种补充。DELETE的前提是首先要满足 ON 和 update 的 where 筛选,否则删除动作不会生效,如果满足则可以删除目标表(不论表前缀是源表还是目标表)中的某些记录;
5、ON 子句里的字段不能被 update 子句更新(考点)。
6、如果一条目标表中的记录被连接到多条源表中的记录,就会产生 ORA-30926:unable to get a stable set of rows in the source tables 错误,反之,如果一条源表中的记录连接到多条目标表中的记录,则目标表中的多条记录被正常更新。
范例2
MERGE INTO products p
USING (select * from newproducts) np
ON (p.product_id = np.product_id)
WHEN MATCHED THEN
UPDATE
SET p.product_name = np.product_name,p.category = np.category
DELETE WHERE (p.category = 'ELECTRNCS')
WHEN NOT MATCHED THEN
INSERT
VALUES (np.product_id, np.product_name, np.category);