![]() |
![]() |
| Paypal | FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
|||||||
| Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
![]() |
|
|
Herramientas | Buscar en Tema | Desplegado |
|
#1
|
|||
|
|||
|
Error de memoria con proceso de Data Pump
Hola amigos he realizado un proceso de Data pump para traspasar todos los datos de una base de datos de nuestra aplicación hacia otra con la misma estructura.
La aplicación es muy sencilla y no tiene ningún tipo de proceso complejo, pero me está dando un quebradero de cabeza en un aspecto determinado. He hecho varias pruebas con diferentes bases de datos con bastante información pero tengo una que llega un momento que me dá error por falta de memoria. ¿Existe alguna posibilidad de controlar ese error o bien, en medio de cada proceso, por ejemplo entre tabla y tabla, liberar memoria? El proceso lo hago con los componentes de la paleta Data Access, la base de datos es FireBird y la versión de Delphi es la 5.
__________________
--== WE RIDE TOGETHER, WE DIE TOGETHER. BAD BOYZ FOR LIVE ==-- .: Mi sitio :. .: Mi trabajo :. |
|
#2
|
||||
|
||||
|
Tal vez si puesieras el código... sería más sencillo.
¿De cuantos registros estamos hablando? ¿Puedes dar más detalles de la Base de Datos que te está dando error?
__________________
Germán Estévez => Web/Blog Guía de estilo, Guía alternativa Utiliza TAG's en tus mensajes. Contactar con el Clubdelphi ![]() P.D: Más tiempo dedicado a la pregunta=Mejores respuestas. |
|
#3
|
|||
|
|||
|
La base de datos que me dá error es la Firebird, la tabla que me dá errores, le he hecho un count y me da un total de 653.398 registros y simplemente lo que hago es acceder a la tabla mediante los componentes tTable de la solapa Data Access y simplemnte lo que hago es asignaciones de un campo a otro. Ya te digo el código funciona perfectamente en todas las bases de datos que he probado excepto en esta, siendo la estructura la misma, ya que ese era el proposito de la aplicación.
El código que utilizo para dicho volcado de datos es el siguiente: Código:
procedure TForm1.btProcesarClick(Sender: TObject);
var
i, j, k, nLinea : Integer;
cTabla : String;
begin
nLinea := 0;
Bloquear_Botones(True);
try
// Abrimos las dos transacciones.
if trTrans1.InTransaction then trTrans1.Rollback;
trTrans1.StartTransaction;
trTrans3.StartTransaction;
// Antes de nada comprobamos si está marcado el check, y si es así
// desactivamos todos los triggers de Insert de la tabla apuntes y
// de la tabla cuentas.
if mmTriggers.Lines.Count <> 0 then Deshabilitar_Triggers;
// Una vez todo listo, procesamos los datos.
for i := 0 to mmPlantilla.Lines.Count - 1 do // Recorremos la lista de tablas.
begin
cTabla := Trim(mmPlantilla.lines[i]);
// Si es la tabla cuentas, debemos realizar dos pasadas.
if UpperCase(cTabla) = 'CUENTAS' then
begin
// Primera pasada
tbTabla1.TableName := cTabla;
tbTabla3.TableName := cTabla;
pgbProceso.Position := 0;
MandarMensaje('Sincronizando tabla [ ' + cTabla + ' - pasada 1 ].');
tbTabla1.Active := True;
tbTabla1.First;
tbTabla3.Active := True;
// Contamos el total de registros
tbTabla1.Last;
tbTabla1.First;
pgbProceso.Max := tbTabla1.RecordCount;
k := 0;
while not tbTabla1.Eof do
begin
lbContador.Caption := IntToStr(k) + ' de ' + IntToStr(pgbProceso.Max);
application.ProcessMessages;
nLinea := tbTabla1.RecNo;
tbTabla3.Insert;
for j := 0 to tbTabla1.Fields.Count - 1 do
begin
if (j <> 9) and (j <> 10) then
tbTabla3.Fields[j].Value := tbTabla1.Fields[j].Value;
end;
pgbProceso.StepIt;
application.ProcessMessages;
tbTabla3.Post;
tbTabla1.Next;
Inc(k);
end;
pgbProceso.Position := pgbProceso.Max;
trTrans3.Commit;
trTrans3.StartTransaction;
tbTabla1.Active := False;
tbTabla3.Active := False;
// Programación de la 2ª pasada en la cual lo que se hace es
// pasar la cuenta del debe y la cuenta del haber.
tbTabla1.TableName := cTabla;
tbTabla3.TableName := cTabla;
pgbProceso.Position := 0;
MandarMensaje('Sincronizando tabla [ ' + cTabla + ' - pasada 2 ].');
tbTabla1.Active := True;
tbTabla1.First;
tbTabla3.Active := True;
tbTabla1.Last;
tbTabla1.Edit;
pgbProceso.Max := tbTabla1.RecordCount;
k := 0;
while not tbTabla1.Eof do
begin
lbContador.Caption := IntToStr(k) + ' de ' + IntToStr(pgbProceso.Max);
application.ProcessMessages;
nLinea := tbTabla1.RecNo;
tbTabla3.Insert;
for j := 9 to 10 do
tbTabla3.Fields[j].Value := tbTabla1.Fields[j].Value;
pgbProceso.StepIt;
application.ProcessMessages;
tbTabla3.Post;
tbTabla1.Next;
Inc(k);
end;
pgbProceso.Position := pgbProceso.Max;
trTrans3.Commit;
trTrans3.StartTransaction;
tbTabla1.Active := False;
tbTabla3.Active := False;
end
else
begin
// Procesamos el resto de las tablas.
if Trim(cTabla) <> '' then
begin
tbTabla1.TableName := cTabla;
tbTabla3.TableName := cTabla;
pgbProceso.Position := 0;
MandarMensaje('Sincronizando tabla [ ' + cTabla + ' ].');
tbTabla1.Active := True;
tbTabla1.First;
tbTabla3.Active := True;
tbTabla1.Last;
tbTabla1.First;
pgbProceso.Max := tbTabla1.RecordCount;
k := 0;
while not tbTabla1.Eof do
begin
lbContador.Caption := IntToStr(k) + ' de ' + IntToStr(pgbProceso.Max);
Application.ProcessMessages;
nLinea := tbTabla1.RecNo;
tbTabla3.Insert;
for j := 0 to tbTabla1.Fields.Count - 1 do
begin
// CONTROL CON EL QUE REVISAMOS SI EN LA RAZON SOCIAL DE LOS REGISTRO DE IVA
// NO SE HA INTRODUCIDO NADA. SI ES ASÍ, ENTONCES PONEMOS DICHO LITERAL.
if UpperCase(cTabla) = 'REGISTRO_IVA' then
begin
if UpperCase(tbTabla1.Fields[j].FieldName) = 'CRAZ_SOCIAL' then
begin
if tbTabla1.Fields[j].Value = '' then
tbTabla3.Fields[j].Value := 'SIN RAZON SOCIAL'
else tbTabla3.Fields[j].Value := tbTabla1.Fields[j].Value;
end
else tbTabla3.Fields[j].Value := tbTabla1.Fields[j].Value;
end
else tbTabla3.Fields[j].Value := tbTabla1.Fields[j].Value;
end;
pgbProceso.StepIt;
application.ProcessMessages;
tbTabla3.Post;
tbTabla1.Next;
Inc(k);
end;
pgbProceso.Position := pgbProceso.Max;
trTrans3.Commit;
trTrans3.StartTransaction;
tbTabla1.Active := False;
tbTabla3.Active := False;
end;
end;
end;
// Si está marcado el Check para actualizar contadores de SurConta, entonces los acutalizamos.
if chkAjSurConta.Checked then Actualizar_Contadores(2);
// Antes de nada validar el resto de las operaciones, procedemos
// a activar de nuevo todos los triggers que hemos desactivado.
if mmTriggers.Lines.Count <> 0 then Habilitar_Triggers;
trTrans3.Commit;
trTrans1.Rollback;
MessageDlg('Proceso de sincronización finalizado.', mtInformation, [mbOK], 0);
MandarMensaje('Proceso de sincronización finalizado.');
except
on E: Exception do
begin
// MessageDlg('Hubo un error en el proceso de sincronización de las bases de datos.', mtError, [mbOK], 0);
MandarMensaje('Error en la siguiente línea [ ' + IntToStr(nLinea) + ' ] de la tabla [ ' + cTabla + ' ] con el siguiente mensaje [ ' + e.message + ' ].');
trTrans1.Rollback;
trTrans3.Rollback;
end;
end;
Bloquear_Botones(False);
end;
__________________
--== WE RIDE TOGETHER, WE DIE TOGETHER. BAD BOYZ FOR LIVE ==-- .: Mi sitio :. .: Mi trabajo :. |
|
#4
|
|||
|
|||
|
Hola,
Hace tiempo hice un programa tambien para traspasar datos de una bd a otra, tal y como comentas que la bd origen es grande no te aconsejo que utilices los componentes TTable, porque entre otras cosas va ha ser muy lento el proceso. Para que te hagas una idea, cuando cuentas los registros de la que tiene 653.398 registros, estas provocando que estos viajen todos por la red!, solo para contarlos. Código:
tbTabla1.Last;
tbTabla1.Edit;
pgbProceso.Max := tbTabla1.RecordCount;
Código:
select * from tabla where codigo = :CODIGO; Código:
qrySelect.ParamByName("CODIGO")->AsString = "0001";
qrySelect.Open();
__________________
Saludos, Bitman |
|
#5
|
|||
|
|||
|
Gracias Toni, modificaré todo el proceso para utilizar dichos componentes.
__________________
--== WE RIDE TOGETHER, WE DIE TOGETHER. BAD BOYZ FOR LIVE ==-- .: Mi sitio :. .: Mi trabajo :. |
![]() |
|
|
|