Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Ayuda con una consulta continua (https://www.clubdelphi.com/foros/showthread.php?t=38124)

vaporlalibre 04-12-2006 09:21:17

Ayuda con una consulta continua
 
Que tal buenas noches, necesito ayuda por favor, mi problema es que hice una agenda como parte de un sistema, en la cual escribi una parte donde introducia una fecha y una hora cualquiera en una base de datos (mysql) por medio de la aplicación, y en un timer la consulta sql que comparaba segundo a segundo si la hora del sistema (en la aplicación la puse en un label conectado a un timer), correspondia a la hora y fecha guardada en la tabla. Al hacer esto me garantizaba una consulta continua asi al llegar la hora señalada me arrojaba un mensaje, avisandome de la tarea pendiente.

Sin embargo segundo a segundo mi cursor cambia por un cursor con simbolo de Sql con el reloj de arena, esto cada segundo que se realiza la consulta SQL y esto pone lento mi aplicación ademas de que se ve anti-estetico, pues en una consulta normal pasa rapido y se ve de vez en cuando, pero asi de esta forma se ve cada segundo.

¿Como podria mejorar esta situación?, les agradecere su respuesta.

roman 04-12-2006 14:02:42

¿Qué componentes estás usando? En dbExpress, la componente SQLConnection tiene la propiedad booleana SQLHourGlass para controlar eso. Eso sí, no me parece lógico que eso sólo sea lo que esté alentando la aplicación.

// Saludos

Bicho 04-12-2006 14:26:39

Cita:

Empezado por roman
Eso sí, no me parece lógico que eso sólo sea lo que esté alentando la aplicación.

Pues a mí, si. Cada segundo está chequeando en la base de datos en busca de avisos pendientes. A mí lo que no me parece lógico, es estar cada segundo haciendo consultas al servidor por eso.

Imaginate que este programa lo tiene 100 usuarios en una empresa mediana, habría 100 consultas de ese programa que está en marcha todo el tiempo sobre el servidor, además de las que se estén haciendo por otro proceso.
Vale que el servidor puede estar preparado y no debería haber problemas, y me estoy yendo por los cerros de úbeda.
Lo que yo quiero decir, es que para un tema como el de avisos, tipo alarma o agenda, no me parace, a mi, la mejor opción la de estar chequeando cada segundo en la base de datos si hay avisos pendiente.

Yo apostaría por tener esa lista en memoria, o en su defecto en un fichero temporal. Por ejemplo, al arrancar la aplicación, que cargue de la base de datos en un fichero, los avisos pendientes para hoy, si se genera algún aviso para hoy, se cargará en el fichero.
Luego que el programa chequee, cada minuto, como minimo, ese fichero y chequee los avisos y los trate según convega.
No sé alomejor tengo una concepción mala, pero para este tipo de avisos (información breve y puntual) prefiero tenerla en memoria o en un fichero de fácil acceso.

No sé, ¿qué opinan ustedes?

Saludos

roman 04-12-2006 15:30:52

Cita:

Empezado por Bicho
Pues a mí, si.

Me refería al cambio de cursor.

// Saludos

Bicho 04-12-2006 16:29:38

Sorry lo entendí mal. :p
Y estoy contigo, no debería ser motivo para el relentizado de la aplicación.

Saludos

vaporlalibre 05-12-2006 02:16:42

Cita:

Empezado por Bicho
Pues a mí, si. Cada segundo está chequeando en la base de datos en busca de avisos pendientes. A mí lo que no me parece lógico, es estar cada segundo haciendo consultas al servidor por eso.

Imaginate que este programa lo tiene 100 usuarios en una empresa mediana, habría 100 consultas de ese programa que está en marcha todo el tiempo sobre el servidor, además de las que se estén haciendo por otro proceso.
Vale que el servidor puede estar preparado y no debería haber problemas, y me estoy yendo por los cerros de úbeda.
Lo que yo quiero decir, es que para un tema como el de avisos, tipo alarma o agenda, no me parace, a mi, la mejor opción la de estar chequeando cada segundo en la base de datos si hay avisos pendiente.

Yo apostaría por tener esa lista en memoria, o en su defecto en un fichero temporal. Por ejemplo, al arrancar la aplicación, que cargue de la base de datos en un fichero, los avisos pendientes para hoy, si se genera algún aviso para hoy, se cargará en el fichero.
Luego que el programa chequee, cada minuto, como minimo, ese fichero y chequee los avisos y los trate según convega.
No sé alomejor tengo una concepción mala, pero para este tipo de avisos (información breve y puntual) prefiero tenerla en memoria o en un fichero de fácil acceso.

No sé, ¿qué opinan ustedes?

Saludos

Eso suena bien, peroexactamente como haria eso, asi ya no cargaria desde el servidor, si no desde memoria local.

roman 05-12-2006 02:40:09

No sé yo que tan malo sea estar consultando al servidor. Verás, yo tengo un sistemita, claro que con pocos usuarios, no más de diez simultáneos, en donde cada cliente debe "avisar" al servidor cada tanto que aún sigue vivo. Esto lo hago cada 30 segundos y no he tenido ningún problema en tres años que ha corrido.

Es que un segundo es un exceso pero normalmente, si una tarea tiene un retraso de 30 segundos nadie se va a morir. Así que podrías también intentar esa opción. Ya si no mejora pruebas otra cosa.

// Saludos

vaporlalibre 05-12-2006 02:44:36

Me gustaria realizar esta consulta cada 5 minutos por lo menos, pero no se como, si alguien pudiera por favor, poner aqui un codigo delphi, donde cada 5 minutos me mande un mensaje, ya yo sustituiria ese mensaje por mi codigo de consulta. Por favor lo agradeceria mucho.

P.D. Utilizo Delphi7

roman 05-12-2006 02:51:20

:confused:

No entiendo, ¿sabes lanzar la consulta cada segundo pero no cada cinco minutos? Es nada más cuestión de cambiar la propiedad Interval del timer: 5*60*1000

// Saludos

vaporlalibre 05-12-2006 03:01:04

no se hacerloca da seguno automaticamente el timer lo hace, pues un timer lo tengo enlzadado a un label para que muestre la hora de esta manera:

procedure TForm11.Timer1Timer(Sender: TObject);
begin
label8.Caption:=timetostr(time);
label4.Caption:=datetostr(date);
end;

El segundo label es para la hora.

Y el segundo timer tengo este codigo, pero quiero que lo ejecute cada 5 minutos, de hecho no he encontrado como manejar eso de los intervalos.

procedure TForm11.Timer2Timer(Sender: TObject);
begin
datamodule.DataModule1.Agenda3.SQL.Text:='select * from agenda where hora=(:valor) and fecha=(:valor2)';
datamodule.DataModule1.Agenda3.Params[0].Value:=label8.Caption;
datamodule.DataModule1.Agenda3.Params[1].Value:=label4.Caption;
datamodule.DataModule1.Agenda3.Open;
if label8.Caption = dbedit1.Text then
begin
showmessage('Tarea pendiente');
end;
end;
procedure TForm11.Edit9KeyPress(Sender: TObject; var Key: Char);
begin
if key=#13 then
begin
bitbtn3.SetFocus;
end;
end;

roman 05-12-2006 03:06:03

Pues eso, la propiedad Interval especifica cada cuanto se ejecuta el evento OnTimer (en milisegundos) Por defecto está en 1000 (1 segundo), por ello tienes que ponerle 5 (minutos) * 60 (segundos) * 1000 = 300000

// Saludos

vaporlalibre 05-12-2006 03:11:33

Excelente, muchas gracias, una ultima pregunta el intervalo de 5 minutos a cada 5 minutos del sistema, o cada 5 minutos a partir de que se inicia la aplicación.

roman 05-12-2006 03:19:54

Cita:

Empezado por vaporlalibre
a cada 5 minutos del sistema

No entiendo a qué te refieres con esto. La primera vez que se ejecuta el evento será a los cinco minutos de que su propiedad Enabled se ponga en true. Como por defecto está en true. entonces se ejecutará la primera vez a los cinco minutos de iniciada la aplicación.

Luego de esto, se ejecutará cada cinco minutos.

// Saludos

Bicho 05-12-2006 09:49:36

Cita:

Empezado por roman
No sé yo que tan malo sea estar consultando al servidor. Verás, yo tengo un sistemita, claro que con pocos usuarios, no más de diez simultáneos, en donde cada cliente debe "avisar" al servidor cada tanto que aún sigue vivo. Esto lo hago cada 30 segundos y no he tenido ningún problema en tres años que ha corrido.

Es que un segundo es un exceso pero normalmente, si una tarea tiene un retraso de 30 segundos nadie se va a morir. Así que podrías también intentar esa opción. Ya si no mejora pruebas otra cosa.

Yo lo que dije es que me parecia excesivo hacer la consulta cada segundo para cada usuario. Pero ponerlo a 30 segundos o cada cinco como al final se ha decidido, no veo problemas. Quizá yendo cada segundo no los habría, pero no sé, no me convence la idea ;)

En cuanto a lo del timer, para quede claro o más liado todavía :p
El timer se activa tiene la propiedad Enabled que es la que dice si el reloj tiene que estar en marcha o no. Si está a True en diseño, al ejecutar la aplicación, arrancará el timer, con lo cual, a los 5 minutos de arrancar hará la consulta.
Por contra, sino está en marcha el timer al arrancar la aplicación o lo has detenido por cualquier cosa, éste queda desactivado hasta que vuelvas tú a darle la propiedad Enabled a True.

Espero quede más claro. No quiero decir que roman lo haya liado, alomejor lo he liado yo, pero en fin...

Saludos

Lepe 05-12-2006 12:39:07

En cuanto a la lista en memoria:

Puedes pedir un listado de las tareas para hoy que devuelva cuanto falta para que llegue (ordenado ascendentemente), por ejemplo fecha_y_hora_de_la_tarea - now) así puedes establecer el intervalo del timer a esa cantidad.

Solo se consulta al servidor una vez. En el evento Ontimer, la tarea ha caducado, lo muestras al usuario y vuelves a pedir la lista al servidor. En realidad no es una lista, al estar ordenado por el tiempo que falta, solo necesitas la primera tarea que caduque (1 registro).

En caso de que alguien agregue/modifique una tarea para hoy, en el servidor haces un Post_event para que los clientes pidan de nuevo esa lista.

Creo que será más eficiente que consultar cada 5 minutos, a menos que se esté continuamente añadiendo tareas para el mismo día desde muchos clientes.

Saludos

roman 05-12-2006 18:20:25

Cita:

Empezado por Lepe
En caso de que alguien agregue/modifique una tarea para hoy, en el servidor haces un Post_event para que los clientes pidan de nuevo esa lista.

¿A qué te refieres con esto?

// Saludos


La franja horaria es GMT +2. Ahora son las 20:53:19.

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