oracle 批量插入数据一次大约8000万条 FRALL插入 处理主键冲突

create or replace package poor_cust is
      procedure proc_import_cust(in_last_date in  varchar2,
                              in_part_name in varchar2,
                              out_flag out  varchar2,
                              out_meg  out varchar2);

end poor_cust;


create or replace package body haida001 is
     procedure proc_import_cust(in_last_date in  varchar2,
                              in_part_name in varchar2,
                              out_flag out  varchar2,
                              out_meg  out varchar2)AS
                
  v_trace_log        MAG_TRACE_JOURNAL%TYPE;--日志
  v_count            pls_integer;--统计记录数
  v_count_fail       number :=0;--失败记录数
  v_count_success   number :=0;--成功记录数
  v_count_total     number :=0; --总记录数
  v_count_skip      number :=0; --跳过记录数
  v_cursor          sys_refcursor; --系统游标
  v_sql             varchar2(2000);--并接sql字符串
  v_regno           GBATCH.TCFED300.REG_NO%type;
  v_rowid           varchar2(200);
   v_row.part_code_15  varchar2(20); --处理成员证件号前15位
  v_row              gmag.cid_poor_custom%type;
  v_err_idx          pls_integer;--出错行位置
  type    sd_tab_type   is table of gmag.cid_custom%rowtype;
  v_tab_sd      sd_tab_type:=sd_tab_type();
  pragma         exception_init(bulk_excp,-24381);
begin
  out_flag:='0';
  out_meg:='proc_import_cust';
  v_count:=0;
  v_trace_log.prog_name:='proc_import_cust';
  v_sql :='select regno,name,poorflag,recod_status,rowid from 表名 partition('||in_partname||') where deaf_flag=0 or deal_flag is null';
  open v_cursor for v_sql;
  loop
     fetch v_cursor into v_regno,v_name,v_ppor_flag,v_record_status,v_rowid;
     exit when v_cursor%notfound;
     v_count_total :=v_count_total+1;--记录总记录数
     v_trim_regno := trim(v_regno);--去掉空格
     v_row.part_head_code:=substrb(v_trim_regno,1,6);--截取字符前6位
     v_row.part_code:=v_trim_regno;
     v_row.part_name:=v_name;
     --处理成员证件号前15位
     v_row.part_code_15:=pckg_gccm_inf_cust_data.func_idcard_convertion('0',v_row.part_code,'1');
     if lengthb(v_row.part_code_15 =18 then
     v_row.part_code_15:='';
     end if;
     --处理游标状态0成功,1失败
     if v_port_flag ='001' then
     v_row.port_status:='1';
     elsif v_poor_flag='002' then
     v_row.port_status:='2';
     else
        v_row.part_status:='999';
     end if;
      if lengb(in-last_date)=8 then
      v_row.last_date:=trim(in_last_date);
      else
      v_row.last_date :=function_getwork_day('001010000');
      end if;
  end loop;
  begin 
       forall INSERT in v_tab_sd.First ..v_tab_sd.last   save Exceptions
        insert into 表名 values v_tab_sd(i);
        if sql%rowcount >0 then --如果又更新得到
        v_count_success:=v_count_success+1;
        else
        --未更新到
        v_count_skip:=v_count_skip+1;
        end if;
       exception when bulk_excp then ---forall 插入报错
       begin
       for INSERT in 1..sql%bulk_exceptions.count loop
       v_err_idx:=sql%bulk_exceptions(i).error_index;
       --处理主键冲突
       if sql%bulk_exceptions(i).error_code='00001' then
       update gmag.cid_poor_custom set part_name=v_tab_sd(v_err_idx).part_name,
             part_code_15=v_tab_sd(v_err_idx).part_code
        where part_head_code=v_tab_sd(v_err_idx).part_code;
            v_count_success:=v_count_success+1;
        end loop;
        
        exception
        when others then
        v_count_fail:=v_count_fail :=v_count_fail+1;
        out_flag :='2';
        out_mess :='更新失败—+表名';
        v_trace_log.err_msg:=substrb('exception'||'||'out_meg||''||sqlerrm ||''||dbms_utility.format_error_backtrace,1,4000);
         pack_pub_loger.proc_trace_info(v_trace_log);
         out_meg:=v_trace_log.err_msg;
         goto next_loop;
      end;
      when others then
      v_count_fail:=v_count_fail+1;
      out_flag:='2';
      out_msg:='gmag.cid.poor_cust';
      v_trace_log.err_msg:='数据迁移失败';
       pack_pub_loger.proc_trace_info(v_trace_log);
       out_meg:=v_trace_log.err_msg;
      goto next_loop;
    end;
    <<next_loop>>
    null;
    commit;
    v_trace_log.err_msg:=substrb('共处理:'||v_count_total||',其中跳过:'||v_count_skip||'失败记录:'||v_count_fail);
      close v_cursor;
     exception 
      when others then
      Rollback;
      out_flag='2';                          
end proc_import_cust;

猜你喜欢

转载自blog.csdn.net/JesseCary/article/details/80066207