Oracle 9i版本引入MERGE INTO语句,其主要用于实现条件入库能力,用于解决对于已有数据更新升级的情况,即可实现不存在数据则插入,存在数据则更新的分支判断形式的更新能力
米虫最近在做老系统跨版本升级,在整理升级 SQL 的时候,无意中学习到 Oracle 中的 MERGE INTO 语法。
MERGE INTO 主要用于解决对于已有数据更新升级的情况。
一般我们升级数据库记录,都是直接写 update 语句,如果这个记录压根不存在,那就尴尬了。
比较常见的做法是,先 delete 记录在 insert 记录,这样可以保证执行不出错。
比如:
DELETE FROM mebugs_run WHERE runid = "GOINDOWN";
commit;
INSERT INTO mebugs_run (runid, runname) VALUES ("GOINDOWN", "THIS_IS_NEW");
commit;
SQL Sever 可以通过 IF...ELSE...实现条件入库。
MySQL 可以通过 REPLACE INTO 实现条件入库(有特殊约束体条件)。
Oracle 9i 引入 INSERT INTO 语句,语法这里不贴了,直接用实例来讲解。
INSERT INTO 语句的强大之处在于可以任意判断某个字段是否存在某个值。
MERGE INTO mebugs_run T1
--检查GOINDOWN这个字符串在mebugs_run表的runid列是否存在
--此处用FROM dual实际上是为了提取一个"GOINDOWN"的字符串,具体原因在下方有解释
USING (SELECT "GOINDOWN" runid FROM dual) T2
--判断mebugs_run T1中的runid字段是不是有"GOINDOWN"
ON ( T1.runid=T2.runid)
WHEN MATCHED THEN
--存在进行UPDATE
--这里更新的是mebugs_run T1中的runid字段是"GOINDOWN"的记录
--需要注意UPDATE的条数不一定是一条
UPDATE SET T1.runname = "MAX_OPEN_FLAG"
WHEN NOT MATCHED THEN
--不存在进行INSERT
INSERT (runid, runname) VALUES ("GOINDOWN", "MAX_OPEN_FLAG");
commit;
在一个同时存在 INSERT 和 UPDATE 语法的 MERGE INTO 语句中,总共 INSERT/UPDATE 的记录数,就是 USING 语句中 alias2(T2)的记录数(alias2 就是上面实例的 T2)。
一定要注意 USING 后面的条件语句,上文实例 FROM dual 最终只会 update 表中 runid = "GOINDOWN"的记录,因为 T2 只会返回一个结果。
如果把
改成
那么这个句子就不一定能够 INSERT 了,因为 ON ( T1.runid=T2.runid)如果不存在该记录的时候条件语句返回直接是空。
所以,MERGE INTO 还是很危险的,说不得本来想更新一条记录,一不小把整个表刷个遍(那你就要绝望了)
重点关注 USING ON 条件语句返回的情况。
使用 MERGE INTO 语句需要清晰理解一个执行过程。
因此,在 MERGE INTO 语句中梳理条件(USING ON 条件语句)是一个非常关键的事情。
温馨提示:系统将通过浏览器临时记忆您曾经填写的个人信息且支持修改,评论提交后仅自己可见,内容需要经过审核后方可全面展示。