Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Conexión con bases de datos
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 30-03-2012
carlo_acp carlo_acp is offline
Miembro
 
Registrado: may 2006
Posts: 26
Poder: 0
carlo_acp Va por buen camino
Refrescar registros de grid automaticamente de la BD sin intervención del usuario

Saludos amigos
Estoy trabajando en una aplicación en la que existe 1 ventana en donde se crean registros ubicada en un terminal. Existe otra ventana, que está en otro terminal, en donde se tiene que visualizar estos registros creados, la idea es que tiene que actualizarse sin intervención del usuario y que sea al momento que se crea el registro en el otro terminal.

Estuve buscando y probando de muchas maneras como hacer esto posible, pero hasta ahora solo tengo una opción que es hacer un timer y que cada "n" segundos haga un refresh del ClientDataSet y me actualice el grid, pero debería esperar el tiempo y en algunas ocasiones es mucho tiempo. Que opinan, como se puede hacer esto, gracias por sus opiniones.
Responder Con Cita
  #2  
Antiguo 30-03-2012
Avatar de ElDioni
[ElDioni] ElDioni is offline
Miembro Premium
 
Registrado: jul 2005
Ubicación: Murcia (España)
Posts: 935
Poder: 19
ElDioni Va por buen camino
Hola,

Al timer le puedes poner el intervalo que quieras, no se porque dices que es mucho tiempo, será mucho si le programas mucho, vamos, digo yo.

Saludos.
__________________
Confórmate con lo que tienes pero anhela lo que te falta.
Responder Con Cita
  #3  
Antiguo 30-03-2012
carlo_acp carlo_acp is offline
Miembro
 
Registrado: may 2006
Posts: 26
Poder: 0
carlo_acp Va por buen camino
Hola gracias por tu respuesta, bueno te explico mas, se trata de un negocio en el cual el tiempo es muy importante, pues los nuevos registros de pedidos deben llegar al instante, tendría que poner un refresh en el timer de 10 seg o 5 seg y ya te imaginas como estaría esa consulta via red, pues habrá tiempos en los cuales no habrá mucho movimiento de pedidos.
Responder Con Cita
  #4  
Antiguo 30-03-2012
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.233
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Creo que otras veces hemos comentado algo similar.
Una opción similar a la que te han comentado, pero más eficiente, es no refrescar la tabla para ver si hay pedidos nuevos (que puede ser una consulta costosa) sino utilizar una pequeña tabla (por ejemplo 1 campo y 1 registro) que te sirva de aviso para saber si tienes que refrescar la tabla real.

De esta forma las consultas casi no generan tráfico por la red (o generan mucho menos) y además no afectan a ninguna tabla importante.

Cuando exista un nuevo pedido, modificas esta tabla de aviso de forma simultánea, y al hacer la consulta sobre esta tabla y detectar que hay nuevo pedido, entonces actualizas la tabla de pedidos.

Otras opciones más complejas, podrían ser utilizar un sistema paralelo, por ejemplo con sockets para no interferir en la Base de Datos, para mandar los avisos.
__________________
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.
Responder Con Cita
  #5  
Antiguo 30-03-2012
carlo_acp carlo_acp is offline
Miembro
 
Registrado: may 2006
Posts: 26
Poder: 0
carlo_acp Va por buen camino
Gracias Neftali, entonces el timer haria consultas a esa tabla si hubo modificaciones y si las hubo, hace la consulta a la tabla con los registros actualizados para actualizar su grid. lo entiendo asi?
Responder Con Cita
  #6  
Antiguo 30-03-2012
Avatar de Chris
[Chris] Chris is offline
Miembro Premium
 
Registrado: abr 2007
Ubicación: Jinotepe, Nicaragua
Posts: 1.678
Poder: 18
Chris Va por buen camino
Cita:
Empezado por carlo_acp Ver Mensaje
Gracias Neftali, entonces el timer haria consultas a esa tabla si hubo modificaciones y si las hubo, hace la consulta a la tabla con los registros actualizados para actualizar su grid. lo entiendo asi?
No, no se trata de utilizar una tabla adicional. Se trata de utilizar la misma tabla de pedidos que ya tienes. Por ejemplo:
Código SQL [-]
Select count(p.id) from pedidos p where p.tomado_fecha > :ultima_fecha_vista

Si la consulta anterior te trae como resultado más de 0 -cero-, entonces refrescas por algún medio no intrusivo la tabla principal.
__________________
Perfil Github - @chrramirez - Delphi Blog - Blog Web
Responder Con Cita
  #7  
Antiguo 31-03-2012
carlo_acp carlo_acp is offline
Miembro
 
Registrado: may 2006
Posts: 26
Poder: 0
carlo_acp Va por buen camino
Gracias Cris, haciendo comparaciones de operaciones y tiempos, corrígeme si me equivoco de estas conclusión:

Tiempo 1
FORMA 1: SELECT count(ID) from Pedidos WHERE horaPedido>HoraActual -2 seg (tabla con todos los pedidos)

vs

FORMA 2: SELECT estado from DBtempo WHERE estado='1' and HoraActual>HoraPedido
(tabla de 1 registro
estado=1 = nuevos registros)

Tiempo 2
en el primer caso: si hay registros
en el segudo caso: si estado='1'
hace la siguiente operación

SELECT from Pedidos WHERE horaPedido>HoraActual -2 seg

si fuera de esta manera, en el segundo caso la busqueda al ser de un solo registro seria mas rápida, de igual manera se tiene que hacer una consulta para saber si hay nuevos pedidos en ese tiempo. Estoy en lo cierto o por favor corríjanme si me equivoco.
Saludos
Responder Con Cita
  #8  
Antiguo 31-03-2012
Avatar de Chris
[Chris] Chris is offline
Miembro Premium
 
Registrado: abr 2007
Ubicación: Jinotepe, Nicaragua
Posts: 1.678
Poder: 18
Chris Va por buen camino
No entiendo exactamente tus comparaciones.

Pero la consulta que yo he utilizado es está:
Código SQL [-]
select p.id from pedidos id where fecha_tomado > :ultima_fecha_que_tengo

Es adaptada a tu escenario. Por otro lado, no sé si será la consulta más eficiente, pero sí es eficiente.

La anterior consulta te devolverá una lista de identificadores de los pedidos que han sido tomados luego de la última fecha y hora que tienes. Luego de hacer el "refresh" recuerda actualizar la variable `ultima_fecha_que_tengo´.

Saludos.
__________________
Perfil Github - @chrramirez - Delphi Blog - Blog Web
Responder Con Cita
  #9  
Antiguo 31-03-2012
carlo_acp carlo_acp is offline
Miembro
 
Registrado: may 2006
Posts: 26
Poder: 0
carlo_acp Va por buen camino
OK Cris, comprendi, gracias por tu ayuda, ya lo estoy implementando, ahora las consultas las estoy haciendo por un SP y los resultados a traves de un SP con SELECT LIST() para que me envie todos los nuevos pedidos, ase sea mas rapido. Gracias a todos por sus comentarios
Responder Con Cita
  #10  
Antiguo 31-03-2012
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
No sé si lo estás haciendo también, pero además de lo que te han dicho, recuerda que una de las ventajas de TClientDataSet es que puedes agregarle registros contenidos en otro TClientDataSet. De esa manera, puedes hacer esto:
Código Delphi [-]
CDS1.AppendData (CDS2.Data, True)
Donde CDS1 podría ser el conjunto de datos que muestra la totalidad de los registros y CDS2 el que se trae solamente los nuevos registros de la base de datos. Así, cada cierto tiempo irás acumulando en CDS1 los nuevos registros generados en la tabla.

Saludos.

Al González.
Responder Con Cita
  #11  
Antiguo 02-04-2012
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.233
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por carlo_acp Ver Mensaje
Gracias Neftali, entonces el timer haria consultas a esa tabla si hubo modificaciones y si las hubo, hace la consulta a la tabla con los registros actualizados para actualizar su grid. lo entiendo asi?
De nada.
Sí, a eso me refería. Hacer consultas sobre una tabla muy pequeña que está vacía o con pocos registros y que además no se utiliza en más lugares de la aplicación (de esa forma no entorpeces otros trabajos).

Cita:
Empezado por Chris Ver Mensaje
No, no se trata de utilizar una tabla adicional. Se trata de utilizar la misma tabla de pedidos que ya tienes. Por ejemplo:
Realmente yo sí me refería a lo que comenta carlo_acp; Se trata de utilizar una pequeña tabla auxiliar para no hacer consultas sobre la tabla de pedidos; Por las varias razones que ya he explicado.
Una consulta como la que tú comentas, reduce el tiempo, pero aun así estás atacando sobre una tabla crítica (algunas veces cuando no es necesario). Si el tema de tiempo es crítico, el usar una tabla intermedia, te asegura que sólo consultarás la de pedidos cuando hay algo nuevo.

Haces más consultas, pero como contrapartida, sobre la tabla crítica son las mínimas necesarias, el resto son sobre una tabla auxiliar que puede tener 1 o 2 campos y 1 o 2 registro (mínima expresión y máxima rapidez).
__________________
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.
Responder Con Cita
  #12  
Antiguo 02-04-2012
carlo_acp carlo_acp is offline
Miembro
 
Registrado: may 2006
Posts: 26
Poder: 0
carlo_acp Va por buen camino
Bueno amigos gracias por sus aportes, lo resolví de esta manera y lo comparto con uds:
1. En el form puse un temporizador de 2 segundos

2. he creado un tabla MovEsta con los campos
ESTA = 0(sin pedidos pendientes) 1(con pedidos pendientes)
HORAING tipo TIMESTAMP (pone la hora en la que se hizo el pedido)

3. en la tabla de Pedidos MovPediD un campo llamado HORAP tipo TIMESTAMP (con la hora del pedido)
4. he creado un TRIGGER en AfterPost de la Tabla de Pedidos
UPDATE movEsta set esta='1', horaIng='now' ;

5. un SP llamado NuevosPedidos

Código SQL [-]
CREATE OR ALTER PROCEDURE NUEVOS_PEDIDOS 
returns (
    lista1 varchar(1000),
    lista2 varchar(1000),
    lista3 varchar(1000))
as
declare variable esta varchar(1);
declare variable horaing timestamp;
declare variable horaact timestamp;
begin
    /* verificar si existe pedidos nuevos */
    SELECT esta, HoraIng, HoraAct from MovEsta
    WHERE esta='1'
    INTO :esta, :horaing,:HoraAct;

    /* si existen nuevos pedidos, devolver listado del pedido */
    if (esta='1') then
        begin
        SELECT list(p.cdpl , ','), list(d.nomb, ','), list(mesa, ',')
        FROM MovPediD P
        LEFT OUTER JOIN DbPlato D ON d.cdpl=P.cdpl
        WHERE P.horaP > :horaAct and P.horaP <=:horaIng
        into :Lista1, :lista2, :lista3 ;
        /* marcar MovEsta.esta=0 y horaAct =now para que ya no tenga pedidos pendientes */
        /* hasta la hora en que se esta actualiando a cocina */
        update MovEsta set esta='0', horaAct='now' ;
    end
 
end

El funcionamiento es de la siguiente manera: cuando realizan el pedido al momento de grabar en la tabla MovPediD, actualiza a MovEsta en el campo ESTA='1' y el HORAING='now'.
El timer en el form, hace la llamada al SP NuevosPedidos y se analiza lo que devuelve:

Código Delphi [-]
   if dat.spNuevos_Pedidos.Params[0].AsString<>'' then
      begin // agregar a cds nuevos pedidos
      CargarNuevosPedidos; /* separar las listas enviadas,  separadas por comas 
                           y crear los registros en el CDS que se muestra en el grid
   end;
Y este es el procedimiento;

Código Delphi [-]
procedure CargarNuevosPedidos;
var xNombre :  string;
begin
   // distribuyendo para cargarlo por registros a cds
   while pos(',', xNombre)>0 do
      begin
      Dat.cdsTempo.Append;
      dat.cdsTempoNOMBRE.AsString:= copy(xNombre, 1, pos(',', xNombre)-1);
      dat.cdsTempo.Post;
      xNombre:= trim(copy(xNombre, pos(',',xNombre)+1, 1000));
   end;
   Dat.cdsTempo.Append;
   dat.cdsTempoNOMBRE.AsString:= xnombre;
   dat.cdsTempo.Post;
end;

de esta forma me esta funcionando, estoy analizando otras opciones pero por lo pronto esta corriendo la aplicacion como se queria. Lo comparto aver si le sirve a alguien

Gracias Neftaly por la idea y a todos amigos,
Saludos
Responder Con Cita
  #13  
Antiguo 12-04-2012
Avatar de PepeLolo
PepeLolo PepeLolo is offline
Miembro
 
Registrado: jun 2003
Ubicación: Fuenlabrada - Madrid - Espagna
Posts: 265
Poder: 21
PepeLolo Va por buen camino
Si usas Interbase en cualquiera de sus versiones, tienes el componente "TIBEvents" que recibe las notificaciones que se han producido en la BBDD.
El uso es muy simple, no necesitas "timer" ni nada parecido, solo este componente que espera una notificación de los eventos que tengas registrados en el componente, ejemplo:

En el trigger de la entidad que quieres que realice la notificación, tienes que poner lo siguiente:

Código SQL [-]
CREATE TRIGGER PR_OP_BU1 FOR PR_OP
ACTIVE BEFORE UPDATE POSITION 1
....
.......
    POST_EVENT 'OP_MOD';  /* Avisar a tu aplicación que existen cambios en la entidad para que realice la actualización automáticamente */

y en el componente TIBEvents lo siguiente:
Código Delphi [-]
With IBEventos do
 begin
   AutoRegister := True;
   DataBase := TuBBDD;
   Events -> 'picha para que salga el asistente y añade tu evento.  "OP_MOD" es el nombre del mio.
 end;

Doble click sobre el evento "onEventAlert":

Código Delphi [-]
procedure Tdm.IBEvtBackupEventAlert(Sender: TObject; EventName: String;
  EventCount: Integer; var CancelAlerts: Boolean);
(*
Fecha : 08/09/2011
Autor : JMCDM
Comentario :
     Detectar modificaciones en la OP
*)
begin
   // Evento lanzado por modificación de OP
   if EventName = 'OP_MOD' then                      // 'OP_MOD' Nombre del evento de BBDD que capturas. 
     frMain.Alerta(OP_MOD);                             // Sentencia que quieres ejecutar.
end;

Ya ta eso es todo.
__________________
PepeLolo
El hombre el único virus que mide más de unas cuantas micras
Responder Con Cita
  #14  
Antiguo 13-04-2012
carlo_acp carlo_acp is offline
Miembro
 
Registrado: may 2006
Posts: 26
Poder: 0
carlo_acp Va por buen camino
Hola PepeLolo, Yo utilizo Firebird con las DbExpress, interesante tu idea, voy a ver si existe lo mismo en firebird para implementarlo y lo comento como me fue, gracias por la idea.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
No muestrar registros en el Grid Paulao Varios 5 24-03-2009 21:17:42
insertar registro en un grid que esta en otro grid @-Soft SQL 7 20-02-2008 18:22:42
insertar n registros en una tabla automaticamente zcatzz SQL 2 08-02-2007 04:42:04
Parlamento europeo desestima intervención comunicaciones Casimiro Notevi Noticias 0 28-09-2005 11:01:33
Registros en un Grid JorgeBec Varios 1 02-04-2005 10:15:49


La franja horaria es GMT +2. Ahora son las 13:50:56.


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
Copyright 1996-2007 Club Delphi