MERGE语句是将有条件更新、插入或者删除操作组合起来
语法如下:
MERGE INTO <target> USING <source>
ON <match-condition>
WHEN [NOT] MATCHED [AND <othe-condition>]
THEN [UPDATE SET ... | DELETE | INSERT VALUES ... | SIGNAL ...]
[ELSE IGNORE]
target:表示操作的对象,表,视图(最终还是操作表)
source:一个查询,或者一个表
match-condition:target和source的链接条件
when matched:表示符合链接条件
when not matched:表示不符合链接条件
other-condition:其他判断条件
signal:用于标注错误处理,如添加一条已经存在的数据的时候,就可以这么写:
signal sqlstate='70001'
set message_text='Record already exists'
else ignore:当不满足前面任何when条件的数据,进行忽略处理。
WHEN MATCHED THEN :MATCHED的情况下,只有UPDATE和DELETE语句可以使用,不能使用INSERT语句。
WHEN NOTE MATCHED THEN :NOTE MATCHED的情况下,不能使用UPDATE和DELETE语句,只可以使用INSERT语句。 (有数据就更新或删除,无数据就插入)
WHEN [NOT] MATCHED AND ( ... AND ... OR ... ) THEN :
除了使用默认的MATCHED/NOT MATCHED以外,还可以指定额外的判断条件,但与MATCHED并列的条件只能用AND,而AND里面可以使用AND和OR。
例:
- ---雇员表(EMPLOYE)
- CREATE TABLE EMPLOYE (
- EMPLOYEID INTEGER NOT NULL,---员工号
- NAME VARCHAR(20) NOT NULL,---姓名
- SALARY DOUBLE---薪水
- );
- INSERT INTO EMPLOYE (EMPLOYEID,NAME,SALARY) VALUES
- (1,'张三',1000),
- (2,'李四',2000),
- (3,'王五',3000),
- (4,'赵六',4000),
- (5,'高七',5000);
- --经理表(MANAGER)
- CREATE TABLE MANAGER (
- EMPLOYEID INTEGER NOT NULL,---经理号
- NAME VARCHAR(20) NOT NULL,---姓名
- SALARY DOUBLE---薪水
- );
- INSERT INTO MANAGER (MANAGERID,NAME,SALARY) VALUES
- (3,'王五',5000),
- (4,'赵六',6000);
经过一段时间,你发现这样的数据模型,或者说表结构设计简直就是一大败笔,经理和雇员都是员工嘛,为什么要设计两个表呢?发现错误后就需要改正,所以你决定,删除经理表(MANAGER)表,将MANAGER 表中的数据合并到EMPLOYE 表中,仔细分析发现,王五在两个表中都存在(可能是干的好升官了),而刘八在EMPLOYE 表中并不存在,现在,我们要求把EMPLOYE 表中不存在的MANAGER都插入到EMPLOYE 表中,存在的更新薪水。该怎么办呢?这个问题并不难,通常,我们可以分两步,如下所示:
- --更新存在的
- UPDATE EMPLOYE AS EM SET SALARY=(SELECT SALARY FROM MANAGER WHERE MANAGERID=EM.EMPLOYEID)
- WHERE EMPLOYEID IN (
- SELECT MANAGERID FROM MANAGER
- );
- ---插入不存在的
- INSERT INTO EMPLOYE (EMPLOYEID,NAME,SALARY)
- SELECT MANAGERID,NAME,SALARY FROM MANAGER WHERE MANAGERID NOT IN (
- SELECT EMPLOYEID FROM EMPLOYE
- );
上面的处理是可以的,但是我们还可以有更简单的方法,就是用Merge语句,如下所示:
- MERGE INTO EMPLOYE AS EM
- USING MANAGER AS MA
- ON EM.EMPLOYEID=MA.MANAGERID
- WHEN MATCHED THEN UPDATE SET EM.SALARY=MA.SALARY
- WHEN NOT MATCHED THEN INSERT VALUES (MA.MANAGERID,MA.NAME,MA.SALARY);
- MERGE INTO EMPLOYE AS EM
- USING MANAGER AS MA
- ON EM.EMPLOYEID=MA.MANAGERID
- WHEN MATCHED AND EM.SALARY<MA.SALARY THEN UPDATE SET EM.SALARY=MA.SALARY
- WHEN MATCHED AND EM.SALARY>MA.SALARY THEN SIGNAL SQLSTATE '70001' SET MESSAGE_TEXT = 'EM.SALARY>MA.SALARY'
- WHEN NOT MATCHED THEN INSERT VALUES (MA.MANAGERID,MA.NAME,MA.SALARY)
- ELSE IGNORE;
- MERGE INTO EMPLOYE AS EM
- USING MANAGER AS MA
- ON EM.EMPLOYEID=MA.MANAGERID
- WHEN MATCHED AND EM.SALARY<MA.SALARY THEN UPDATE SET EM.SALARY=MA.SALARY
- WHEN MATCHED AND EM.SALARY>MA.SALARY THEN DELETE
- WHEN NOT MATCHED THEN INSERT VALUES (MA.MANAGERID,MA.NAME,MA.SALARY)
- ELSE IGNORE; 声明:转载http://blog.youkuaiyun.com/shangboerds/article/details/4775422仅供学习、研究、欣赏