Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Liberar memoria (https://www.clubdelphi.com/foros/showthread.php?t=36765)

vicvil 23-10-2006 18:32:04

Liberar memoria
 
Hola que tal!!!
Necesito orientación.
Estoy haciendo una actualización de tablas Paradox, en un programa en tiempo de ejecución. Estas tablas estan almacenadas en distintas carpetas, estas carpetas pueden ser una a mas de 100. Cuando el programa parte, comienza a actualizar las tablas incluso tiene una barra con porcentaje de avance. Todo va bien, llega hasta la ultima carpeta, se ve que pasa por todas las tablas, pero cuando las reviso me ha actualizado solo 60 de 100.
Los query que utilizo los abro y cierro y libero con free para que libere la memoria (que es lo que se supone que hace el query.free), pero aun asi no actualiza las tablas de las restantes carpetas y ni siquiera envia mensaje de error de memoria. Solo pasa por las tablas pero no las actualiza cuando pasa por el query.ExecSql
Si alguien tiene alguna idea a que se debe agradeceré su opinión.

PD. Creo que puede ser un problema de memoria, si es asi ¿como puedo liberarla durante el proceso?

javicho_villa 23-10-2006 19:11:12

Cierra y vuelve abrir tu conexion
 
Hola :
Bueno a mi me pasaba algo similar cuando utilizo Querys para actulizar data(insertar, editar y eliminar), entonces lo que hago es cerrar y volver abrir la conexion, si es Data Module, cierro y abro la conexion despues comienzo a abrir cada tabla nuevamente.

ojala te sirva.

saludos

Sick boy 23-10-2006 19:24:38

Puedes poner el codigo que utilizas??

No se por qué lo haces, quizas tenga sentido, pero creo que no necesitas liberar el query después de cada consulta, solo al finalizar.

¿ Que actualizas en las tablas ?? Son muchos registros??

Quizas sea la solución cerrar el datamodule, pero si es así, es un desastre y una perdida de tiempo tener que abrir y cerrar cada vez. O no??

Además, ningun mensaje de error??
Puede ser que se ejecute el query pero que no afecte a ningún registro de esa tabla??

Bueno, con un poco más de info igual sacamos algo.

Lepe 23-10-2006 19:30:32

Si se ejecuta y no obtienes errores, es que no hay nada que actualizar. Ya, parece una "respuesta rápida", pero no es así.

Despues de ejecutar el Query, mira en su propiedad query1.RowsAffected, si te dice que es cero, no había nada que actualizar. Igual la sentencia sql busca en mayúsculas, minúsculas, o simplemente hay un espacio de más o de menos.

Para este tipo de cosas es muy interesante un Log (al menos en un memo) con los detalles, algo del tipo:
Código:

SQL a ejecutar: update mitabla set campo = '' where codigo = 3;
Resultado: 3 Registros afectados

SQL a ejecutar: update mitabla set campo = '' where codigo = 21;
Resultado: 1500 Registros afectados

Lo que sí debes hacer es un TTable.FlushBuffers en el afterpost de las tablas, pero al usar Querys no creo que sea viable.

Ya puestos, podrías incluir un Memo para escribir a mano sentencias SQL y otro Memo donde ver los resultados de esa consulta con un Botón de "Abrir Consulta" y otro de "Ejecutar Consulta".


Edito: Ya veo que Sick boy se me adelantó. Otra cosa que puede ocurrir es que no cambie de carpeta correctamente. Al ser tablas paradox, antes de cambiar la ruta de carpeta, tienes que cerrar el Database y la Session, modificar la ruta y despues reabrirlo. (si no usas esos componentes... deberías)

Saludos

vicvil 23-10-2006 20:46:18

Pensando que podia ser por memoria, comence a abrir, modificar la tabla, cerrar y liberar con free eso para hacer la prueba, ya que como dice Sick Boy no es necesario hacerlo sino hasta el final, pero lo hice para probar. Pero aun asi sigue con el problema.
Las tablas que se actualizan con el programa pueden ser cientos, eso va a depender de la cantidad de información que tenga el usuario.
Con respecto a la ruta, eso está bien definida, yo he ruteado el programa y pasa por las tablas que debería actualizar pero no lo hace, es mas puede actualizar la tabla inmediatamente anterior dentro de la misma carpeta pero la proxima ya no lo hace. Y como dije anteriormente no envia ningun mensaje de error.

dec 23-10-2006 20:51:55

Hola,

Yo iba a responder lo mismo que Lepe:

Cita:

Empezado por Lepe
Si se ejecuta y no obtienes errores, es que no hay nada que actualizar. Ya, parece una "respuesta rápida", pero no es así.

Es que si no hay nada que actualizar las consultas de actualización se ejecutan en la aplicación, pero, el gestor de la base de datos no llega a ejecutarlas: porque averigua que no hay nada que actualizar.

No sé si ocurre en Paradox: desde luego en MySQL sí que ocurre así.

Yo iba a añadir también si siempre ocurre que se actualizan las tablas de la 1 a la 60 y las siguientes no, porque, esto echaría por tierra la idea de que "si no hay nada que actualizar no se actualiza".

Quiero decir, que, si de las 160 tablas se actualizan la 1, 5, 10, 30, etc., es posible entonces que ocurra lo que Lepe refiere y yo machaco: el resto de las tablas no cambiaron, por tanto no hay nada que actualizar y la consulta no produce error alguno pero tampoco actualiza nada... como es lógico.

Lepe 24-10-2006 12:34:02

¿Puedes poner algún trozo de código que uses para crear la conexión, alias, y ejecución de las consultas?

Si sigue pasando, hay algo que se nos escapa, algo que para ti no tiene importancia pero es el kid de la cuestión. ¿las carpetas están compartidas en otros ordenadores?, ¿ están siendo usadas por otra aplicación?.

¿Qué sentencias sql estas ejecutando?

Saludos

vicvil 24-10-2006 15:24:48

Como les decía ayer, no es que las tablas no tengan nada que actualizar, les estoy agregando campos y además estoy creando nuevas tablas dentro de las carpetas.

Este es un pedazo de código como lo estoy haciendo:

Query:=TQuery.Create(Application);
Query.DatabaseName:= Ruta de cada carpeta
Query.SessionName:= nombre de sesion;
Query.SQL.Clear;
Query.SQL.Add('Alter table tabla1 Add campo Char(10)');
try
Query.ExecSql
except
end;
Query.close;
//
Query.SQL.Clear;
Query.SQL.Add('Alter table tabla2 Add campo Char(1)');
try
Query.ExecSql
except
end;
Query.close;

etc

Lo que estoy tratando de hacer es por ejemplo lo siguiente:
Se tienen mas de 100 carpetas de Empresas, dentro de cada una de ellas tenemos las carpetas de los periodos de trabajo (años) que pueden ser n y dentro de ellas las carpetas con los meses (1 a 12). Yo estoy actualizando las tablas de las carpetas de los meses, de los periodos y de las empresas. Pero se actualiza por ejemplo hasta la Empresa 60 hasta el periodo x hasta el mes 5 y de ahi en adelante ya no actualiza nada. ¿Que entrete no?

Lepe 25-10-2006 12:19:14

Cita:

Empezado por vicvil
¿Que entrete no?

No. Era de esperar.

Código Delphi [-]
try
Query.ExecSql
except
end;
Al no poner nada entre el except... end, estas diciendo que si ocurre alguna excepción, simplemente se la coma con patatas y siga adelante. Por eso no muestra ningún mensaje de error. Debes hacer lo siguiente:
Código Delphi [-]
try
Query.ExecSql
except
  on E: Exception do
  ShowMessage(Format('Atencion error de tipo: %s', [E.ClassName]));
end;
Ver si da fallos en ejecución y despues controlar los fallos que dé.

Código Delphi [-]
try
Query.ExecSql
except
  On E: << el tipo que te haya mostrado el ShowMessage anterior>> do
  begin
     << controlar de la forma oportuna >>
  end;
  On E: << otro tipo de fallo >> do
  begin
  << lo que sea>>
  end
  else
    ShowMessage(Format('Atencion Error No esperado de tipo: %s', [E.ClassName]));
end;

Por cierto, sigo diciendo que un Log del estilo que comenté es necesario para este tipo de cosas.

Saludos

vicvil 25-10-2006 16:33:38

Hice lo que me indicaste pero me aparece un error mas bien generico entiendo. Me envia el mensaje EDBEngineError para mi esto no me dice mucho, debe haber alguna forma de ver el error exacto. ¿Como se puede hacer?

Lepe 26-10-2006 01:22:31

Quizás el mensaje de la propia excepción te ayude algo más:

Código Delphi [-]
  ShowMessage(Format('Atención error de tipo: %s. Mensaje de error: %s', [E.ClassName, E.Message]))

Saludos

vicvil 26-10-2006 15:58:34

Hice la prueba.
Me arrojó el mensaje de error, pero este mensaje me dejó mas consternado aun, ya que dice lo siguiente:

"Too many open databases
Alias"

¿Por que si yo estoy cerrando los querys?
Incluso hice la prueba cerrando y liberandolos y aun asi me envía el error.
Yo creo que no libera la memoria como debería hacerlo.

Lepe 26-10-2006 16:19:13

Lo que nadie te ha dicho de paradox, es que al situar un TTable, TQuery, etc en una ventana, delphi crea implicitamente un objeto TSession y un objeto TDatabase, y los usa para gestionar todos esos objetos de acceso a datos que has puesto.

Para una aplicación simple, (de escritorio), de un solo usuario, accediendo a tablas que forman parte "de una sola base de datos", no hace falta echar cuenta a esos dos individuos, pero al realizar tareas avanzadas como tú estas haciendo, sí hay que tenerlo en cuenta.

Según dice son "Alias abiertos" y creo que viene por aquí el problemilla:
Cita:

Empezado por Lepe
Otra cosa que puede ocurrir es que no cambie de carpeta correctamente. Al ser tablas paradox, antes de cambiar la ruta de carpeta, tienes que cerrar el Database y la Session, modificar la ruta y despues reabrirlo. (si no usas esos componentes... deberías)

Cuando cambias el DatabaseName (para redirigir la entrada a otra carpeta), debes cerrar la session, el Database, configurar las nuevas rutas y abrirlos de nuevo.

Lo que está ocurriendo, es que al asignar el DatabaseName, crea "una conexión nueva" a la carpeta, dichas conexiones se van acumulando en memoria hasta que se excede el límite permitido.

2 Soluciones:
- Usa Database.Connected := false cada vez que vas a cambiar de carpeta.
- Añade un TDabase y un TSession y configuralos a tu gusto.

Saludos

vicvil 30-10-2006 17:14:38

Gracias, eso queria saber.
Voy a hacer las pruebas.


La franja horaria es GMT +2. Ahora son las 14:49:32.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi