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;
n,i,Max:integer;
fTextFile:TextFile;
value:single;
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;
i:=0;
progress1.Min:=0;
progress1.Position:=0;
AssignFile(fTextFile,'x:\padron_retenciones.txt');
Reset(fTextFile);[/color]
progress1.Min := 0;
progress1.Max := LineasCount(); progress1.Position:= 0;
DM.WriteTrans.StartTransaction;
While Not Eof(fTextFile) Do
begin
ReadLn(fTextFile, s);
Progress1.Position:= i;
Application.ProcessMessages;
sCuit :=Copy(s,30,11);
sAliRet:='0';
sAliPer:='0';
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;
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; end
else
DM.WriteTrans.StartTransaction; 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;
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
Linfo.Caption:='Verificando clientes...';
PInfo.Refresh;
Actualizar_Alicuotas_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