Oracle sql merge要插入和删除但不能更新

时间:2013-07-17 20:28:58

标签: sql oracle merge insert sql-delete

有没有办法使用oracle merge来插入和删除但不更新?

我有一个表,表示与另一个表中的单个行相关的一组值。我可以通过删除所有值并添加回新集来更改值集,或者通过有选择地删除一些并添加其他值来更改值集,但我有兴趣在可能的情况下将其作为单个语句。

以下是更新的工作示例。为了完成这项工作,我必须添加dummy,以便可以更新一个不在on条件下的列。有没有办法只删除和插入没有虚拟列来更新?

on条件中的任何列都不在update set列表中,即使它实际上没有更新。

create table every_value ( the_value varchar2(32) );
create table paired_value ( the_id number, a_value varchar2(32) , dummy number default 0 );
-- the_id is a foreign_key to a row in another table

insert into every_value ( the_value ) values ( 'aaa' );
insert into every_value ( the_value ) values ( 'abc' );
insert into every_value ( the_value ) values ( 'ace' );
insert into every_value ( the_value ) values ( 'adg' );
insert into every_value ( the_value ) values ( 'aei' );
insert into every_value ( the_value ) values ( 'afk' );

-- pair ace and afk with id 3
merge into paired_value p using every_value e
on ( p.the_id = 3 and p.a_value = e.the_value )
when matched then update set dummy=dummy+1
delete where a_value not in ('ace','afk')
when not matched then insert (the_id,a_value)
values (3,e.the_value)
where e.the_value in ('ace','afk');

-- pair ace and aei with id 3
-- should remove afk, add aei, do nothing with ace
merge into paired_value p using every_value e
on ( p.the_id = 3 and p.a_value = e.the_value )
when matched then update set dummy = dummy+1
delete where a_value not in ('ace','aei')
when not matched then insert (the_id,a_value)
values (3,e.the_value)
where e.the_value in ('ace','aei');

-- pair aaa and adg with id 4
merge into paired_value p using every_value e
on ( p.the_id = 4 and p.a_value = e.the_value )
when matched then update set dummy = dummy+1
delete where a_value not in ('aaa','adg')
when not matched then insert (the_id,a_value)
values (4,e.the_value)
where e.the_value in ('aaa','adg');

select * from paired_value;

我在oracle 10g中尝试了这个,并使用此sqlfiddle,oracle 11g。

2 个答案:

答案 0 :(得分:16)

不,您无法删除merge命令尚未更新的行 以下是文档:http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016.htm

  

指定DELETE where_clause以清除表中的数据   填充或更新它。 受此条款影响的唯一行是   目标表中由合并更新的那些行   操作即可。 DELETE WHERE条件评估更新的值,而不是   由UPDATE SET ... WHERE评估的原始值   条件。如果目标表的一行符合DELETE   条件但不包含在ON子句定义的连接中,   然后它不会被删除。在目标上定义的任何删除触发器   每行删除都会激活表格。

这意味着,行必须才能更新。 Hovewer,在UPDATE使用与DELETE之后使用的相同WHERE子句后,您不需要更新所有行

when matched then update set dummy=dummy
    where a_value not in ('ace','afk')
delete 
    where a_value not in ('ace','afk')

答案 1 :(得分:1)

我发现你可以将列设置为自己:

MERGE ...
WHEN MATCHED THEN 
   UPDATE SET a_value = a_value WHERE a_value not in ('ace','afk')
   DELETE WHERE a_value not in ('ace','afk')

这消除了对虚拟列的需要。