在工作中,我们经常会有这样的需求,特别是在交易的时候,判断终端的交易流水号是否连续,即可判断终端上的数据是否有丢失。下面总结了如何处理这种情况,比较通用,红色部分就是实现的原理
--2.执行语句块
declare
isExists number ;
v_zdbh char(8);
v_begin char(10);
v_first number;
v_min number;
v_max number;
begin
delete from tmp_lost;
v_zdbh := '01011198';
v_begin := '2011/09/30';
v_first :=1;
v_min :=0;
v_max :=0;
for cur_lost in (select * from
(
select min(zdjyxlh) min ,max(zdjyxlh) max,rn from -- 得到连续的段的开始位置和结束位置,rn的值,
(
select a.*, rownum,(a.zdjyxlh-rownum) as rn from --在原始结果集上加上rownum列,通过排序字段-rownum值,能过这个值来判断中间是否连续
(
select t.* from ic_xfmxz t where zdbh=v_zdbh and to_char(jyrq,'yyyy/mm/dd')=v_begin order by zdjyxlh --先进行排序,得到原始的结果集。这里的排序字段为zdjyxlh
) a
) aa group by rn --进行分组,
)bb
order by bb.min) loop
v_max := cur_lost.min;
dbms_output.put_line(cur_lost.min||','||cur_lost.max||','||cur_lost.rn||','||v_min||','||v_max);
if v_first<>1 then
for cur_wrz in (select * from ic_wrzlsz t where t.zdbh =v_zdbh
and t.zdjyxlh>v_min and t.zdjyxlh<v_max
order by t.zdjyxlh ,t.jyrq desc ,t.jysj desc) loop
dbms_output.put_line('zdjyxlh='||cur_wrz.zdjyxlh);
select count(*) into isExists from tmp_lost tmp where tmp.zdjyxh = cur_wrz.zdjyxlh and tmp.zdbh=cur_wrz.zdbh;
if isExists =0 then
insert into tmp_lost values(cur_wrz.lsh,cur_wrz.zdbh,cur_wrz.zdjyxlh,cur_wrz.ickh,cur_wrz.icjyxh,cur_wrz.jyje,cur_wrz.icye,cur_wrz.jyrq,cur_wrz.jysj);
end if;
end loop;
else
v_first:=0;
end if;
v_min := cur_lost.max;
end loop;
commit;
EXCEPTION
when others then
dbms_output.put_line(sqlcode||'='||sqlerrm);
rollback;
end;