MERGE INTO
      TABLE_A
USING (...)
ON (...)
WHEN NOT MATCHED THEN
 INSERT () VALUES (sequence.nextVal)
WHEN MATCHED THEN
  UPDATE ...上面这个SQL, 如果只执行UPDATE的话,sequence也会被增长,这是为什么亚

解决方案 »

  1.   

    update的原理是先删除原来的数据,然后再插入新的数据.所以sequence.nextVal同样增长.例如
    id , name
    1    aupdate tb set name = 'b' where id = 1是先删除id = 1的记录,然后插入id = 1 , name = 'b'
      

  2.   

    值得关注
    做了个试验
    create sequence a_seq;
    create table a as select rownum a1,rownum*2 a2 from dual connect by rownum<1000;
    create table b as select rownum+300 a1,rownum*(-1) b1 from dual connect by rownum<300;--确定下当前的a_seq.nextval值
    select a_seq.nextval  from dual;merge into b using a
    on (a.a1=b.a1)
    when matched then 
    update set b.b1=a.a2
    when not matched then
      insert (b.a1,b.b1) values(a_seq.nextval,a.a2);--再看看
    select a_seq.currval  from dual;
    --涨了999
    --将merge句去掉update子句再执行一次
    rollback;
    merge into b using a
    on (a.a1=b.a1)
    when not matched then
      insert (b.a1,b.b1) values(a_seq.nextval,a.a2);
    --看看涨了多少
    select a_seq.currval  from dual;
    --还是999,和a表的记录条数相同
    可以看出,merge代码中,每读取a中的一条记录,就会解析一次when not matched中的insert语句,造成序列值增长。和update没有关系
      

  3.   

    为什么Oracle会这样实现?怪怪的
      

  4.   

    update是这样啊?能给出相关的资料吗 我想看看
      

  5.   

    你整个代码是怎么样的?把NOT MATCH里不写看看会怎么样?
      

  6.   

    when not matched去掉我也试了,序列值不涨
    但是这是没有意义的,因为如果将此句去掉,这个merge into里根本就没有序列
      

  7.   

    你UPDATE肯定原来有数据的啊
    照目前的讨论下来的结果,变成这样了
    有INSERT语句,当MATCH时,同样会执行一遍INSERT,造成  sequence.nextVal执行
    所以我建议把INSERT语句去掉,同样应该是可以执行的
    这样是不是可以理解成MERGE语句执行UPDATE时并不需要先执行INSERT一遍?
      

  8.   

    不是执行insert,而是merge into执行的时候,每比对一条记录都会将matched和not matched都分析一次,造成序列增长。将2部分开写成2个merge into应该可以避免这个问题。还是很奇怪就是..seqname.nextval如果作为条件使用,比如if seqname.nextval>100 then..
    每比较一次,序列值也会增长