ORACLE游标在重复数据后追加递增值

有一个需求是要把某一表中同一个投融资合同编号下重复的抵押物编号后面追加01,02.。。分组之后每一组后面的抵押物编号都需要添加且都从01开始,因为在写这个存储的时候遇到过一些问题,且oracle游标我不太熟悉,在用游标的过程中发现oracle和sqlserver的游标在循环更新方面好像有些不同,我不知道是因为我的逻辑或数据库两者本身有问题还是其他原因,所以记录下来方便以后学习和回顾。。。

--需求:判断一个表中同一个投融资合同编号下是否有重复抵押合同号,
--如果有重复则依次在每个投融资合同编号下对应的抵押物编号后面追加01,02.。。
--注:每个投融资合同编号下重复的抵押物编号后面全部追加01,02.。。
declare
  v_index   number;--索引,用于在需要更改值后添加,如01,02
  --以下三个变量用于接收结果集中的主键值
  v_xtxmbh  varchar2(40);
  v_trzhtbh varchar2(40);
  v_dyhtbh  varchar2(40);
  --定义一个游标变量
  cursor c_job is
  --该语句用于获取待处理结果集,这里获取的是dywxx_test表中xtxmbh, trzhtbh, dyhtbh三个字段
  --重复的数据,说白了就是该表中重复数据
    select t.*
      from dywxx_test t,
           (select xtxmbh, trzhtbh, dyhtbh, count(dyhtbh) as dyhtbhs
              from dywxx_test
             group by xtxmbh, trzhtbh, dyhtbh
             having count(xtxmbh)>1 and count(trzhtbh)>1 and count(dyhtbh)>1
             ) tt
     where t.xtxmbh = tt.xtxmbh
       and t.trzhtbh = tt.trzhtbh
       and t.dyhtbh = tt.dyhtbh
     order by t.xtxmbh, t.trzhtbh, t.dyhtbh;
     --定义一个游标变量
  c_row c_job%rowtype;
begin
  v_index   := 1;--索引给出默认值1
  --以下三个主键变量默认值给予空
  v_xtxmbh  := '';
  v_trzhtbh := '';
  v_dyhtbh  := '';
  --循环待处理数据,即以上查出的结果集
  for c_row in c_job loop
    --如果三个主键变量全部相等,则索引加1(注:如果dyhtbh重复,则三个主键一定会重复)
    if (c_row.xtxmbh = v_xtxmbh and c_row.trzhtbh = v_trzhtbh and
       c_row.dyhtbh = v_dyhtbh) then
      v_index := v_index + 1;--递增索引
    --如果三个主键有不相等的值,则索引恢复默认值1,因为如果有主键不相等则抵押物编号
    --即dyhtbh后加01,02.。。,且给每个主键变量值赋予获取的主键值
    --注:如果有主键值不相等则说明循环进入了第二组抵押物编号重复的数据,这里说的第二组数据是指
    --不同投融资合同编号的另外一组重复数据
    else
      v_index   := 1;
      v_xtxmbh  := c_row.xtxmbh;
      v_trzhtbh := c_row.trzhtbh;
      v_dyhtbh  := c_row.dyhtbh;
    end if;
    --如果三个主键值全部相等,则执行以下逻辑,即先添加一条数据,之后删除重复数据
    --之所以先添加后删除是因为更新语句对应条件的值被更改后第二次被更改则被更改的值会出现混乱
    if (c_row.xtxmbh = v_xtxmbh and c_row.trzhtbh = v_trzhtbh and
       c_row.dyhtbh = v_dyhtbh) then
       --如果索引小于10,则抵押物编号DYHTBH后面追加'0' || v_index,拼成01,02.。。
       if v_index<10 then
      insert into dywxx_test
      values
        (c_row.ORGANKEY,
         c_row.TBJGBH,
         c_row.XTXMBH,
         c_row.TRZHTBH,
         c_row.DYHTBH || '0' || v_index,
         c_row.DYWMC,
         c_row.DYWLX,
         c_row.DYWCSPGJZ,
         c_row.CSPGRQ,
         c_row.FDCLDYWXXFL,
         c_row.DYWFCTXQZHM,
         c_row.DYWJZMJ,
         c_row.DYWTDSYMJ,
         c_row.DYWTDTXQZHM,
         c_row.DYWQCSX,
         c_row.ZJDYWPGJZ,
         c_row.ZJDYWPGRQ,
         c_row.FLAG);
         end if;
         --如果索引>=10,则直接在抵押物编号后面追加v_index,即10,11.。。。
         else
           insert into dywxx_test
      values
        (c_row.ORGANKEY,
         c_row.TBJGBH,
         c_row.XTXMBH,
         c_row.TRZHTBH,
         c_row.DYHTBH || v_index,
         c_row.DYWMC,
         c_row.DYWLX,
         c_row.DYWCSPGJZ,
         c_row.CSPGRQ,
         c_row.FDCLDYWXXFL,
         c_row.DYWFCTXQZHM,
         c_row.DYWJZMJ,
         c_row.DYWTDSYMJ,
         c_row.DYWTDTXQZHM,
         c_row.DYWQCSX,
         c_row.ZJDYWPGJZ,
         c_row.ZJDYWPGRQ,
         c_row.FLAG);
    end if;
    --删除原有的抵押物编号重复数据
    delete from dywxx_test t where t.xtxmbh=c_row.xtxmbh and t.trzhtbh=c_row.trzhtbh and t.dyhtbh=c_row.dyhtbh;
  end loop;--循环结束
  commit;--提交处理后数据
end;
原文地址:https://www.cnblogs.com/liudi1992/p/2657372.html