表a:不断的更新数据,时刻产生新的id号的数据;表b:跟a一样的结构,通过DBLINK实时取表a的数据过来。我从表a取数据到b,其中每次轮询完只取a的新产生的id号,需要有新id的判断,没有的就插入,已经有的更新。 程序里还得包括异常抛出和输出错误日志的功能,因为要监控这个job的运行情况~~~~~ 

解决方案 »

  1.   

    a表得有标志位来表示哪些已经update过了,否则只能全表扫。
      

  2.   

    我从表a取数据到b,其中每次轮询完只取a的新产生的id号,需要有新id的判断,没有的就插入,已经有的更新。如果数据量不大,可以试着全表数据进行MERGE INTO
      

  3.   


    merge into 在另一个帖子里面已经被你否决了。你要记录每行出错数据的信息。。
      

  4.   

    实时的话可以用触发器
    如果用job定时对b表进行更新,应该在a表中有个最后更新时间字段吧
    根据这个字段来判断id是否是新产生的
    更新b表用merge into
      

  5.   

    declare
       cursor c1 is select id, c2 from a;
       type t_a is table of a%rowtype;
       result_a t_a;
    begin
       open c1;
       loop
          fetch c1 bulk into result_a
          limit 1000;
          begin
             forall i in result_a.FIRST .. result_a.LAST save exceptions
                insert into b values(i.id,i.c2);
          -- when insert fail, collect error record and do update logic
          exception
             when others then
                for j in 1 .. sql%bulk_exceptions.count loop
                   begin
                      update b set c2 = result_a(result_a(sql%bulk_exceptions(j).error_index).c2)
                      where b.id = result_a(sql%bulk_exceptions(j).error_index).id;
                   -- when update fail, put error msg
                   exception 
                      when others then
                         dbms_output.put_line('update fail record' || result_a(sql%bulk_exceptions(j).error_index).id);
                   end;
                end loop;
          end;
          exit when c1%notfound;
       end loop;
       close c1;
    end;
    /merge似乎没办法将错误行定位,使用触发器代价太高。如果有更新的时间点字段,因为a表还在做更新操作,所以时间点之后的纪录仍然可能会有重复的纪录。以上代码未经测试,大意如此,
    过程是,对时间点以后的a表数据直接执行插入操作,如果插入失败,则捕获dup_val_on_index异常,
    执行更新操作,如果更新也失败,则将错误行的记录具体值输出。使用forall时加以limit限制,是为了保证a表纪录数过多时不会占用太大内存空间。