我从表a取数据到b,其中每次轮询完只取a的新产生的id号,需要有新id的判断,没有的就插入,已经有的更新。如果数据量不大,可以试着全表数据进行MERGE INTO
merge into 在另一个帖子里面已经被你否决了。你要记录每行出错数据的信息。。
实时的话可以用触发器 如果用job定时对b表进行更新,应该在a表中有个最后更新时间字段吧 根据这个字段来判断id是否是新产生的 更新b表用merge into
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表纪录数过多时不会占用太大内存空间。
merge into 在另一个帖子里面已经被你否决了。你要记录每行出错数据的信息。。
如果用job定时对b表进行更新,应该在a表中有个最后更新时间字段吧
根据这个字段来判断id是否是新产生的
更新b表用merge into
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表纪录数过多时不会占用太大内存空间。