MERGE表,匹配时什么也不做

use*_*665 6 sql oracle merge match sql-merge

我在2个不同的模式中有一个表DOMAINS,其中包含列ID,NAME,CODE,DESCRIPTION.

对于新架构中存在的任何NAME,它应该使用现有ID而不进行任何合并; 对于那些新的NAME记录,它应该使用旧架构的ID插入.

MERGE INTO DOMAINS A
USING (SELECT ID,NAME,CODE,DESCRIPTION FROM <Old Schema 6.1>.DOMAINS@DB_MIG_61_TO_74) B
ON(A.NAME = B.NAME)
WHEN MATCHED **<do nothing>**
WHEN NOT MATCHED THEN INSERT(A.ID,A.NAME,A.CODE,A.DESCRIPTION) 
VALUES(B.ID,B.NAME,B.CODE,B.DESCRIPTION);
Run Code Online (Sandbox Code Playgroud)

我如何解释上述查询中"无所事事"的部分?

Bar*_*han 8

举个例子 :

SQL> create table domains( id int, name varchar2(50), code varchar2(50), description varchar2(50));

SQL> insert into domains values(1,'Domain A','D.A.','This is Domain A');

SQL> merge into domains A
  using 
 (select 2 id, 'Domain A' name, 'D.A.' code, 'This is Domain A' description from domains) b
     on ( a.name = b.name )
   when not matched then insert( a.id, a.name, a.code, a.description ) 
                         values( b.id, b.name, b.code, b.description );

SQL> select * from domains;

ID  NAME        CODE    DESCRIPTION
--  --------   -----  ----------------
1   Domain A    D.A.  This is Domain A

SQL> delete domains;

SQL> insert into domains values(1,'Domain A','D.A.','This is Domain A');
-- we're deleting and inserting the same row again

SQL> merge into domains A
  using 
 (select 2 id, 'Domain B' name, 'D.B.' code, 'This is Domain B' description from domains) b
     on ( a.name = b.name )
   when not matched then insert( a.id, a.name, a.code, a.description ) 
                         values( b.id, b.name, b.code, b.description );

ID  NAME        CODE    DESCRIPTION
--  --------   -----  ----------------
1   Domain A    D.A.  This is Domain A
2   Domain B    D.B.  This is Domain B
Run Code Online (Sandbox Code Playgroud)

部分可用于无需改变.

SQL> create table domains( id int, name varchar2(50), code varchar2(50), description varchar2(50));

SQL> insert into domains values(1,'Domain A','D.A.','This is Domain A');

SQL> merge into domains A
  using 
 (select 2 id, 'Domain A' name, 'D.A.' code, 'This is Domain A' description from domains) b
     on ( a.name = b.name )
   when not matched then insert( a.id, a.name, a.code, a.description ) 
                         values( b.id, b.name, b.code, b.description );

SQL> select * from domains;

ID  NAME        CODE    DESCRIPTION
--  --------   -----  ----------------
1   Domain A    D.A.  This is Domain A

SQL> delete domains;

SQL> insert into domains values(1,'Domain A','D.A.','This is Domain A');
-- we're deleting and inserting the same row again

SQL> merge into domains A
  using 
 (select 2 id, 'Domain B' name, 'D.B.' code, 'This is Domain B' description from domains) b
     on ( a.name = b.name )
   when not matched then insert( a.id, a.name, a.code, a.description ) 
                         values( b.id, b.name, b.code, b.description );

ID  NAME        CODE    DESCRIPTION
--  --------   -----  ----------------
1   Domain A    D.A.  This is Domain A
2   Domain B    D.B.  This is Domain B
Run Code Online (Sandbox Code Playgroud)

SQL小提琴演示


小智 7

Oracle SQL语法支持没有任何when matched then update子句.

drop table ft purge;
create table ft (c1 number, c2 varchar2(10));

drop table ld purge;
create table ld (c1 number, c2 varchar2(10));

insert into ft values (1,'a');
insert into ld values (1,'b');
insert into ld values (2,'c');
commit;

merge into ft 
using ld
on (ft.c1 = ld.c1) 
when not matched then
insert (c1,c2) values (ld.c1,ld.c2);

select * from ft;

C1  C2
--- ---
1   a
2   c

2 rows selected.
Run Code Online (Sandbox Code Playgroud)