Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 06-12-2008
Avatar de StartKill
StartKill StartKill is offline
Miembro
 
Registrado: ene 2004
Posts: 299
Poder: 21
StartKill Va por buen camino
RefreshRecord - DBExpress con Interbase

Saludos al foro..

Estoy con Delphi 2006, Interbase 7.5 y componentes Dbexpress.

Tengo dos tablas (productos y grupos):
Productos
codigo_p
descrip_p
codigo_grupo


Grupos
codigo_grupo
nombre_grupo


Un FK de codigo_grupo entre ambas tablas

Tengo un componente:
SQLDataSet1=
'select p.codigo_p, p.descrip_p, p.codigo_grupo, g.nombre_grupo_p
from productos p
left join grupo p.codigo_grupo = g.codigo_grupo?'

En ProviderFlag estan asi:
codigo_p = [pfInUpdate,pfInWhere,pfInKey]
descrip_p = [pfInUpdate]
codigo_grupo = [pfInUpdate]
nombre_grupo = []

un DataSetProvider1 cuya propiedad UpdateMode = upWhereKeyOnly

Al final todo ello apuntando a un ClientDatset-->CDS

Cuando abro la consulta y la muestro en una grilla los datos son correctos.

Cuando añado/insert un nuevo registro y lo grabo con CDS.ApplyUpdates(0) no muestra el valor g.nombre_grupo.
Le doy un RefreshRecord tampoco se refresca el campo g.nombre_grupo.
(Con el IBExpert e visto que si hay algun valor en el campor codigo_grupo y por consecuencia deberia visualizarse un valor para g.nombre_grupo)

Pero si doy un CDS.Refresh o un "Reopen(CDS.close/CDS.open)" si se refresca el campo g.nombre_grupo del nuevo registro, pero es de suponer que he vuelto a leer todos los registros, cosa que no deseo, solo necesito refrescar el registro activo.

A la espera de su ayuda.

Startkill
Lima-Perú
Responder Con Cita
  #2  
Antiguo 06-12-2008
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
¡Hola!

Es normal lo que obtienes.

Al aplicar los cambios al servidor (llamando al método ApplyUpdates) no hay un mecanismo que automáticamente realice una nueva consulta. En cliente-servidor y esquemas superiores esta es una de las grandes diferencias con respecto a las bases de datos de escritorio, donde después de guardar un registro el motor te devuelve en automático una "imagen" de lo que al final quedó registrado.

En cliente-servidor es diferente, y aunque algunos motores ya implementan "respuestas al guardado", no es algo que esté estandarizado ni soportado plenamente por dbExpress, ADO, IBX, etc. Se da por entendido que el servidor no responde con datos de campos a una operación Insert o Update. Es necesaria una nueva consulta.

Ahora, cuando haces un ClientDataSet.RefreshRecord, sólo estás diciéndole que le pida al proveedor la última copia que fue leída del registro actual, la cual se encuentra todavía en algún lugar de la memoria, pero NO se realiza una nueva consulta Select.

Ante esto, hace ya tiempo que implementé mi propio "RefreshRecord consultante". La esencia del mismo es:

1. Eliminar de memoria la fila actual del conjunto de datos cliente.
2. Ignorar por completo ese registro llamando a MergeChangeLog.
3. Consultar con otro conjunto de datos cliente el registro que se quiere volver a leer, mediante un proveedor conectado a una consulta SQL que tenga como parámetro de entrada el "ID" del registro a consultar.
4. Copiar de este segundo conjunto de datos el registro recién leído al primer conjunto de datos. Esto último lo consigues con una sentencia como:

Código Delphi [-]
CDS1.AppendData (CDS2.Data, True);

Parece mucho trabajo, pero, como ya has visto, la poco deseable alternativa es llamar al método Refresh, el cual haría una nueva y costosa consulta de todas las filas, cuando realmente sólo necesitas releer una de ellas.

Si optas por implementar el mecanismo de los cuatro pasos que mencioné, te recomendaría encapsularlo en alguna función, o, mejor aún, en clases de objetos derivadas, para que cada vez que lo uses sea más conciso tu código (entre otras ventajas).

Espero haber orientado un poco. No dejes de contarnos.

Al González.

Última edición por Al González fecha: 22-01-2009 a las 20:23:07.
Responder Con Cita
  #3  
Antiguo 07-12-2008
Avatar de StartKill
StartKill StartKill is offline
Miembro
 
Registrado: ene 2004
Posts: 299
Poder: 21
StartKill Va por buen camino
Holas al foro.

Requeria hacer un refresh a un solo registro, "estoy utilizando componentes dbexpress" para un aplicativo datasnap. En el componente ClientDataSet existe un metodo RefreshRecord, este metodo no lee nuevamente el registro en la base de datos....

Aqui la explicación de Al González:
Cita:
Ahora, cuando haces un ClientDataSet.RefreshRecord, sólo estás diciéndole que le pida al proveedor la última copia que fue leída del registro actual, la cual se encuentra todavía en algún lugar de la memoria, pero NO se realiza una nueva consulta Select.

Ante esto, hace ya tiempo que implementé mi propio "RefreshRecord re-consultor". La esencia del mismo es:

1. Eliminar de memoria la fila actual del conjunto de datos cliente.
2. Ignorar por completo ese registro llamando a MergeChangeLog.
3. Consultar con otro conjunto de datos cliente el registro que se quiere volver a leer, mediante un proveedor conectado a una consulta SQL que tenga como parámetro de entrada el "ID" del registro a consultar.
4. Copiar de este segundo conjunto de datos el registro recién leído al primer conjunto de datos. Esto último lo consigues con una sentencia como:

CDS1.AppendData (CDS2.Data, True);

Parece mucho trabajo, pero, como ya has visto, la poco deseable alternativa es llamar al método Refresh, el cual haría una nueva y costosa consulta de todas las filas, cuando realmente sólo necesitas releer una de ellas.
Al González, gracias por tu respuesta, hice lo que indicaste...

Para probar lo hice en un boton - no esta encapsulado ó en algun objeto que seria lo ideal, "lo voy hacer"

Código Delphi [-]
procedure TForm1.Button12Click(Sender: TObject);
Var
  xClave:Integer;
begin
   //asegurase de que no existan pendientes
   //ya que MergeChangeLog lo eliminaria del Delta
    if ClientDataset3.ChangeCount>0 then
       showmessage('Hay datos pendientes en caché, aplicarlos antes del refresh')
    else begin
       //salvo el contenido del campo clave del registro a refrescar
       xClave:=ClientDataset3fcod_mast.AsInteger;
       //Leer de la Base de datos el registro a refrescar
       CDS_refresh.Close;
       CDS_refresh.Params.ParamByName('xClave').AsInteger:=xClave;
       CDS_refresh.Open;
       //borrar el registro que deseo refrescar
       ClientDataset3.Delete;
       //borrar datos de Delta
       ClientDataset3.MergeChangeLog; 
       // añadir el registro - RefreshRecord
       ClientDataset3.AppendData (CDS_refresh.Data, True);
    end;
end;

Saludos

Your friend

StartKill
Lima-Perú

Última edición por StartKill fecha: 12-12-2008 a las 06:28:36. Razón: Ortografía
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
DbExpress o interbase felixgo Conexión con bases de datos 0 27-09-2005 12:20:43
Conexion dbexpress e interbase- URGENTE mortiz Conexión con bases de datos 1 31-08-2004 13:08:02
InterBase + dbExpress y CGI Slash Internet 4 27-04-2004 15:52:40
Duda dbExpress + Interbase ¥0n1 Conexión con bases de datos 2 05-07-2003 14:55:48
dbExpress e Interbase SKaRCHa Firebird e Interbase 6 08-05-2003 14:42:29


La franja horaria es GMT +2. Ahora son las 10:05:14.


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