Ver Mensaje Individual
  #9  
Antiguo 03-07-2014
cloayza cloayza is offline
Miembro
 
Registrado: may 2003
Ubicación: San Pedro de la Paz, Chile
Posts: 913
Reputación: 23
cloayza Tiene un aura espectacularcloayza Tiene un aura espectacular
Estimado hgiacobone si me lo permite, quisiera proponer algunos cambios, pienso que podría mejorar el rendimiento.

1) Leer el archivo de texto sin pasar por la carga de este a un TStringList.
2) Evitar el uso de tablas temporales y realizar la inserción o actualización en la tabla final (PADRON)
3) Modificar procedimiento almacenado que realiza el merge de las tablas temporales.

Por supuesto puede ser que mi mirada no cumpla con sus requerimientos, A ver que le parecen.

Código Delphi [-]
Const
     COMMIT_RECORD=10000;
var
  InicioSesion, FinSesion: TDateTime;
  s, m, sMsgErrores, sCuit: string;
  sAliPer,sAliRet:string;
  //MyStringList:TStringList;
  n,i,Max:integer;

  {Definicion de variable para archivo de texto}
 fTextFile:TextFile;
  value:single;

    {Funcion que cuenta las lineas que tiene el archivo de texto}
    Function LineasCount:Integer;
    Var
       Line:String;
    Begin
         Result:=0;
         while Not Eof(fTextFile) do
         Begin
              ReadLn(fTextFile,Line);
              Inc(Result);
         End;
         Reset(fTextFile);
    End;[/color]

Begin
    InicioSesion:= Now;

    //MyStringList := TStringList.Create;

    i:=0;
    progress1.Min:=0;
    progress1.Position:=0;

    AssignFile(fTextFile,'x:\padron_retenciones.txt');
    Reset(fTextFile);[/color]

    progress1.Min     := 0;
    progress1.Max     := LineasCount(); //MyStringList.Count;
    progress1.Position:= 0;

    DM.WriteTrans.StartTransaction;

    {Ciclo principal de lectura del archivo de texto}
    While Not Eof(fTextFile) Do
    begin
         {Lectura de una linea}
         ReadLn(fTextFile, s);

         Progress1.Position:= i;

         Application.ProcessMessages;

         sCuit  :=Copy(s,30,11);
         sAliRet:='0';
         sAliPer:='0';

         {Este trozo de código tambien se puede mejorar...}
         if (s[1]='P') then
         begin
             sAliPer:=Copy(s,48,4);
             Value:=StrToCurr(Copy(sAliPer,1,1)+'.'+Copy(sAliPer,3,2));
         end
         else
         begin
             sAliRet:=Copy(s,48,4);
             Value:=StrToCurr(Copy(sAliPer,1,1)+'.'+Copy(sAliPer,3,2));
         end;

         {Llamada al procediento que realiza la inserción p actualización}
         DM.SP100.StoreProcName:='SP_PADRON_MERGE';
         DM.SP100.ParamByName('Tipo').AsString   := s[1];
         DM.SP100.ParamByName('Cuit').AsString   := sCuit;
         DM.SP100.ParamByName('Alicuota').AsFloat:= Value;
         DM.SP100.Prepare;
         DM.SP100.ExecProc;

         if ((i mod COMMIT_RECORD) = 0) then
         begin
             try
                LInfo.Caption:=Format('Grabando bloque %d/%d...', [i, Max ]);
                Pinfo.Refresh;

                if (DM.WriteTrans.InTransaction) then
                begin
                     DM.WriteTrans.Commit;
                     DM.WriteTrans.StartTransaction;  //Inicia una Trans consecutiva
                end
                else
                    DM.WriteTrans.StartTransaction;  //Fuerza iniciar una Trans
             Except
               on E:Exception do
               begin
                    DM.WriteTrans.Rollback;
                    Bien:= false;
                    PInfo.Visible:=False;
                    sMsgErrores:= sMsgErrores + 'Error al grabar bloque de datos.'#13+E.Message;
                    Break;
               end;
             end;
         end;
    end;{lineas_del_archivo}


    //Compruebo si hay un resto sobre ultimos 500 con transac activa los guarda tambien
    if (DM.WriteTrans.InTransaction) then
    begin
         try
            DM.WriteTrans.Commit;
         except
           on E:Exception do
           begin
                DM.WriteTrans.Rollback;
                Bien:= false;
                PInfo.Visible:=False;
                sMsgErrores:= sMsgErrores + 'Error al guardar el RESTO.'#13+E.Message;
                Break;
           end;
         end;
    end;

    Linfo.Caption:='Guardando datos. Aguarde...';
    PInfo.Refresh;

    DM.WriteTrans.StartTransaction;
    TRY
        {Ya no sería necesario porque ya esta todo junto}

        {DM.SP101.StoredProcName:='';
        DM.SP101.StoredProcName:='SP_PADRON_MERGE';
        DM.SP101.ExecProc;
        DM.WriteTrans.Commit;}

        Linfo.Caption:='Verificando clientes...';
        PInfo.Refresh;

        Actualizar_Alicuotas_Clientes; //actaulizamos Tabla clientes

        FinSesion:= Now;
        m:= Format('(Tiempo: %s)', [ TimeToStr(FinSesion - InicioSesion) ]);

        Linfo.Caption:='Importación Finalizada - ' + m;
        PInfo.Refresh;

        Application.MessageBox(PChar('Proceso finalizado correctamente.'#13 + m),
          'Aviso', MB_OK+MB_ICONINFORMATION);

    Except
      on E:Exception do
      begin
       DM.WriteTrans.Rollback;
       Bien:= FALSE;
       PInfo.Visible:=False;
       MessageDlg('Error al actualizar el padrón.'#13#13'Tipo de error:'#13+E.Message, mtError, [mbOk],0);
      end;
    End;
end;

Código SQL [-]

Create or Alter procedure SP_PADRON_MERGE (
    TIPO char(10),
    CUIT integer,
    ALICUOTA integer)
as
begin
     if (Tipo='R') then
        UPDATE or INSERT INTO PADRON (CUIT, ALICUOTA_RETENCION) VALUES (:CUIT, :ALICUOTA ) MATCHING (CUIT);
     else
        UPDATE or INSERT INTO PADRON (CUIT, ALICUOTA_PERCEPCION) VALUES (:CUIT, :ALICUOTA ) MATCHING (CUIT);
end

Espero que mi pequeño aporte le ayude a mejorar el rendimiento de su proceso.

NOTA: Tome en cuenta que el conteo de las lineas del archivo para mostrar la barra de progreso puede ser omitida para mejorar mas el rendimiento

Saludos cordiales
Responder Con Cita