点击蓝色字关注“SQL数据库运维”,回复“SQL”获取2TB学习资源!
Oracle Merge语法
MERGE INTO target_table --目标表(需要执行插入、修改、删除操作的表)
USING source_table --使用USING子句指定要更新或插入的数据源。源可以是表、视图或子查询的结果。
ON search_condition --匹配条件
WHEN MATCHED THEN --操作语句
UPDATE SET col1 = value1, col2 = value2,...
WHERE <update_condition>
[DELETE WHERE <delete_condition>]
WHEN NOT MATCHED THEN
INSERT (col1,col2,...)
values(value1,value2,...)
WHERE <insert_condition>;
下面来仔细看看上面Merge语句的语法详解:
-
首先,指定要在INTO子句中更新或插入的目标表(target_table)。 -
其次,指定要更新或插入USING子句中的数据源表(source_table)。 -
第三,指定合并操作在ON子句中更新或插入的搜索条件(匹配条件)。
-
如果结果为true,则Oracle使用源表(source_table)中的相应数据更新该行。 -
如果任何行的结果为false,则Oracle将源表(source_table)中相应的行插入到目标表(target_table)中。
当想要在单个操作中组合多个INSERT,UPDATE和DELETE语句时,Merge语句变得很方便。
因为Merge是确定性语句,所以不能在同一个Merge语句中多次更新目标表的同一行。
Oracle 10g中的MERGE提供了在执行数据操作时清除行的选项. 你能够在WHEN MATCHED THEN UPDATE子句中包含DELETE子句. DELETE子句必须有一个WHERE条件来删除匹配某些条件的行.匹配DELETE WHERE条件但不匹配ON条件的行不会被从表中删除。
要执行Merge语句,必须在源表上具有INSERT和UPDATE对象权限。如果使用DELETE子句,则还必须在目标表上具有DELETE对象特权。
CREATE TABLE members (
member_id NUMBER PRIMARY KEY,
first_name VARCHAR2(50) NOT NULL,
last_name VARCHAR2(50) NOT NULL,
rank VARCHAR2(20)
);
--快速新建另外一个表
CREATE TABLE member_staging AS
SELECT * FROM members;
使用以下INSERT语句将示例数据插入到members和member_staging表中:
--插入数据
-- insert into members table
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(1,'Abel','Wolf','Gold');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(2,'Clarita','Franco','Platinum');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(3,'Darryl','Giles','Silver');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(4,'Dorthea','Suarez','Silver');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(5,'Katrina','Wheeler','Silver');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(6,'Lilian','Garza','Silver');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(7,'Ossie','Summers','Gold');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(8,'Paige','Mcfarland','Platinum');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(9,'Ronna','Britt','Platinum');
INSERT INTO members(member_id, first_name, last_name, rank) VALUES(10,'Tressie','Short','Bronze');
-- insert into member_staging table
INSERT INTO member_staging(member_id, first_name, last_name, rank) VALUES(1,'Abel','Wolf','Silver');
INSERT INTO member_staging(member_id, first_name, last_name, rank) VALUES(2,'Clarita','Franco','Platinum');
INSERT INTO member_staging(member_id, first_name, last_name, rank) VALUES(3,'Darryl','Giles','Bronze');
INSERT INTO member_staging(member_id, first_name, last_name, rank) VALUES(4,'Dorthea','Gate','Gold');
INSERT INTO member_staging(member_id, first_name, last_name, rank) VALUES(5,'Katrina','Wheeler','Silver');
INSERT INTO member_staging(member_id, first_name, last_name, rank) VALUES(6,'Lilian','Stark','Silver');
将members表中的数据更新到member_staging表时,应该执行以下操作:
-
更新成员id为1,3,4和6的行记录,因为表中这些成员的排名或姓氏是不同的。
-
要插入成员id为7到10的行记录,这是因为这些行存在于members表中,但不存在于member_staging表中。
总共有8行数据需要合并。参考以下图示 :
以下是一次性执行所有这些操作的MERGE
语句。
MERGE INTO member_staging x --目标表(需要执行插入、修改、删除操作的表)
USING (SELECT member_id, first_name, last_name, rank FROM members) y --数据源表
ON (x.member_id = y.member_id) --匹配条件
--匹配到的数据,按照数据源表的数据进行更新
WHEN MATCHED THEN
UPDATE SET x.first_name = y.first_name,
x.last_name = y.last_name,
x.rank = y.rank
WHERE x.first_name <> y.first_name OR
x.last_name <> y.last_name OR
x.rank <> y.rank
--目标表中匹配不到数据源表的数据,在这里将匹配不到的数据插入目标表(指数据源中有的,而目标表中没有的数据,可以执行insert操作)
WHEN NOT MATCHED THEN
INSERT(x.member_id, x.first_name, x.last_name, x.rank)
VALUES(y.member_id, y.first_name, y.last_name, y.rank)
Merge语句根据member_id列中的值(参见上面的ON子句),将member表中的每一行与member_staging表中的每一行进行比较。
如果两个表的member_id列中的值相等,Merge语句只有在两个表的first_name,last_name或rank列的值不相等时,才将members表中的first_name,last_name或rank列的值作为member_staging对应列的值来更新,否则它将members的行直接插入member_staging表。
查询结果验证:
SELECT * FROM members ;
SELECT * FROM member_staging order by member_id asc;
Oracle按照预期返回了8行合并数据,最终结果显示目前两个表的数据实现同步。
1、merge无法多次更新同一行,也无法更新和删除同一行
2、当源表和目标表不匹配时:
若数据是源表有目标表没有,则进行插入操作
若数据是源表没有而目标表有,则进行更新或者删除数据操作
3、当源表和目标表匹配时:
进行更新操作或者删除操作
Oracle官方参考文档:https://docs.oracle.com/database/121/SQLRF/statements_9017.htm#SQLRF01606
SQL Server官方参考文档:https://learn.microsoft.com/zh-cn/sql/t-sql/statements/merge-transact-sql?view=sql-server-ver16
点击关注“SQL数据库运维”,后台或浏览至公众号文章底部点击“发消息”回复关键字:进群,带你进入高手如云的技术交流群。后台回复关键字:SQL,获取学习资料。
动动小手点击加关注呦☟☟☟
发表评论