Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

Refrescar datos en DBGrid con Firebird

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Bases de Datos
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Refrescar datos en DBGrid con Firebird Responder citando

Hola
Conseguida la conexión en red, ahora, con dos usuarios apuntando a la misma tabla, no puedo refrescar los datos de un DBGrid. Es decir, un usuario introduce un dato nuevo en una tabla (PRECIOS), y no hay forma de verlo reflejado en el otro equipo a menos que desconecte el Database, y lo vuelva a conectar. He probado desconectando el DataSet, Refresh, etc..
En el foro he visto que había artículos pero se referían a un refresco a tiempo real. No es mi caso, pero en mi aplicación (TPV), los filtros que realizo a la Tabla PRECIOS son tan numerosos que veo una carga excesiva (aparte de que es lento) el tener que desconectar el Database (o sea, desconectarme de todas las tablas que uso) y volver a conectar cuando quiera ver los datos reales de la tabla. NO QUIERO VER EL DATO EN EL OTRO EQUIPO A TIEMPO REAL, SÓLO QUIERO VERLO.

Gracias de antemano.
_________________
LA INSPIRACIÓN EXISTE, PERO TIENE QUE ENCONTRARTE TRABAJANDO
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

Saludos, requieres primero un Commit en el cliente que escribe, por el lado
de los otros clientes basta con cerrar la tabla o consulta y reabrirla.
Si requieres cierta inmediatez utiliza los eventos de firebird disparados en un trigger After Insert y capturado con un TIBEvents.
Algo de codigo:
Código:
//En el trigger
Post_Event 'Nuevo Registro'
//En el cliente que escribe evento AfterPost de la tabla
Tabla->IBTransaction->Commit();
Tabla->Open();//Debes abrir de nuevo todas las tablas que usen la misma transaccion
//En el cliente que va a leer Verificar que no este en modo de edicion
//Evento OnEventAlert
if(Tabla->State==dsBrowse)
{
 Tabla_>Close();
 Tabla->Open();
}

Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

El proceso que te comenta alfredo es correcto, pero si aun no quieres estar conectando y desconectando tu Tabla, pues esto tambien es una carga excesiva de la red, pudes agregar unas cuantas lineas mas y alguna modificacion a tu componente Transacction, realizando estas operaciones, puedes mantener tu conexión "viva" y seguir trabajando correctamente

Cita:
Transacction:

AllowAutoStart: true
AutoStopAction: saCommitRetaining
Params:
write
isc_tpb_read_committed
isc_tpb_rec_version
isc_tpb_nowait


Generas un Trigger que se presente cada vez que realices un Update o Delete, (estos dos ultimos eventos evitan la carga de la red, pues lo que realmente nos interesa es que el registro haya sido modificado o borrado) al insertar no, pues pueden estar dando de alta a nuevos productos, los cuales tus estaciones no se deben enterar hasta que esos registros sean usados por ellas.)
Código:

SET TERM ^ ;

CREATE TRIGGER T_PRODUCTOS FOR PRODUCTOS
ACTIVE AFTER UPDATE OR DELETE POSITION 10
AS
BEGIN
  POST_EVENT 'UpdatePRODUCTOS';
END^
SET TERM ; ^


Cuando generas el proceso de grabado para la tabla (recuerda que se ha modificado el componente Transacction), debe establecer un codigo como esto, ayudate de un try-catch, para verificar que se ha grabado correctamente a sabiendas que si resulta el trigger se "dispara".

Código:
   try
   {
      // producto grabado con exito, se dispara el trigger
      tablaProductos->Post();
      tablaProductos->ApplyUpdates();
      tablaProductos->Transaction->CommitRetaining();
   }
   catch(...)
   {
      tablaProductos->Cancel();
      tablaProductos->CancelUpdates();
      tablaProductos->Transaction->RollbackRetaining();
      MessageDlg("Error en Escritura",mtWarning,TMsgDlgButtons() << mbYes ,0);
      // si no se graba, avisamos al usuario, y las demas
      // estaciones ni se enteran.
   }


y en el evento del TIBEvents algo como esto.
Código:

if(EventName=="UpdatePRODUCTOS")
{
   TDataSetState oldEstado = tablaProductos->State;
   if(tablaProductos->Active == true)
   {
      switch( ccsgDataSet->State )
      {
         case dsEdit:
            tablaProductos->Refresh();
         break;
         case dsBrowse:
            tablaProductos->ApplyUpdates();
            tablaProductos->Transaction->CommitRetaining();
            tablaProductos->Refresh();
         break;
      }
   }
   if ( oldEstado == dsEdit)
   {
      tablaProductos->Edit();
   }
}


Esta forma aun que un poco mas larga te permite tener un poco mas de control, haciendo que los productos se actualicen en "tiempo real".

Como tiempo real se conoce cuando 2 estaciones estan en el mismo registro al mismo tiempo, y existe un cambio echo por alguna de ellas, este cambio debe ser reflejado en la otra.

Nota la forma de evitar un Lock, dentro de la tabla, para realizar el refresh que permite que el otro cliente vea con detalle si hay un cambio sin alterar su estado de edicion, si esta en edit, se refrescan los cambios y si solo esta observando el registro, se graba y se presentan los datos.


Saludos. Cool
_________________
Cool
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.