Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Actualizar datos dbgrid (https://www.clubdelphi.com/foros/showthread.php?t=83122)

darkerviti 13-05-2013 17:29:45

Actualizar datos dbgrid
 
Buenas tardes,

Mi problema es el siguiente, tengo un dbgrid conectado a un datasoruce, este esta a un clientdataset que tiene como maestro a otro clientdataset,
el grid me muestra perfectamente la informacion hasta que inserto un nuevo elemento, dicho elemento se inserta correctamente en bbdd pero no aparecen los datos insertados en el grid, y no solo eso, he probado a cerrar el clientdataset y abrirlo, a hacer un refresh y nada, solo me funciona cuando salgo de la aplicación, el código que ejecuto al insertar es el siguiente:
Código Delphi [-]
procedure TNewClass.bbtOkClick(Sender: TObject);
var
  Error : Boolean;
begin
  Error := False;
  if edName.Text = '' then
    ShowMessage('Please fill all fields')
  else
  begin
    if DM.cdsClassNew.Locate('label;idstudy', VarArrayOf([edName.Text,DM.cdsStudySel.FieldByName('id').AsInteger]),[]) then
      showmessage('Class already exists, please select another name for the class.')
    else
    begin
      if MessageDlg('Do you want to create this new class?', mtConfirmation, mbYesNo, 0) = mrYes then
      begin
        try
          DM.cdsClassNew.Insert;
          DM.cdsClassNew.FieldByName('label').AsString := edName.Text;
          DM.cdsClassNew.FieldByName('idstudy').AsInteger := DM.cdsStudySel.FieldByName('id').AsInteger;
          DM.cdsClassNew.Post;
          DM.cdsClassNew.ApplyUpdates(0);
          DM.cdsClassNew.Refresh;
          DM.cdsClassNew.Close;
          DM.cdsClassNew.Open;
          DM.cdsClass.Refresh;
          showmessage('Class created successfully');
        except
          showmessage('Operation cannot be done, please try again');
        end;
      end;
    end;
  end;
end;

Seguro que es una tontería, pero llevo mucho tiempo con el código delante y ya no lo veo.

Muchas gracias.

Al González 13-05-2013 17:37:30

¿Qué valores hay en las propiedades MasterSource, MasterFields e IndexFieldNames?

darkerviti 13-05-2013 17:44:27

Cita:

Empezado por Al González (Mensaje 460359)
¿Qué valores hay en las propiedades MasterSource, MasterFields e IndexFieldNames?

Esto es lo que tiene cdsClassNew:

MasterSource --> dsStudySel
MasterFields --> id
IndexFieldNames --> idstudy

Esta parte funciona bien o, por lo menos, si funciona mal, la información que muestra el dbgrid es la que espero, el problema se produce al insertar un elemento.

Al González 13-05-2013 18:05:23

Gracias por retroalimentar. Hagamos una prueba:

Justo después de ejecutarse la línea "DM.cdsClassNew.Insert;", ¿qué valor hay en el campo IDStudy, y en el campo ID del conjunto de datos maestro? Y justo antes del Post, ¿qué valor hay en el campo IDStudy?

Otra pregunta, ¿usas Filter u OnFilterRecord?

Una más, ¿si sólo haces el Post (sin lo que está después de él), también desaparece el registro?

Por último, ¿seguro que dsStudySel está conectado a cdsStudySel?

darkerviti 13-05-2013 18:44:50

Cita:

Empezado por Al González (Mensaje 460366)
Gracias por retroalimentar. Hagamos una prueba:

Justo después de ejecutarse la línea "DM.cdsClassNew.Insert;", ¿qué valor hay en el campo IDStudy, y en el campo ID del conjunto de datos maestro? Y justo antes del Post, ¿qué valor hay en el campo IDStudy?

Otra pregunta, ¿usas Filter u OnFilterRecord?

Una más, ¿si sólo haces el Post (sin lo que está después de él), también desaparece el registro?

Por último, ¿seguro que dsStudySel está conectado a cdsStudySel?


Vale, he estado haciendo pruebas, si comento todo lo demás a partir del Post, en el grid se muestra bien, pero no aparece por la bbdd, además, si intento insertar una segunda vez, me da el siguiente error:
Código:

raised exception class EDBClient with message 'Key violation.'
Si después del post sí que hago el ApplyUpdates, inserta en bbdd y muestra en el grid, pero si intentan insertar una segunda vez, suelta el mismo error que antes.
Si meto el refresh, ya no aparece en el grid, inserta bien en bbdd y me deja insertar todas las veces que yo quiera.
En cuanto a los valores que tienen:
- Justo después del insert, el campo idstudy esta vacio y el id del maestro tiene como valor 7.
- Justo antes del post el campo idstudy ya tiene también el valor 7.

No utilizo ni Filter ni OnFilterRecord y sí, dsStudySel está conectado a cdsStudySel, lo he revisado por si las moscas.

Muchas gracias por el interés.

Al González 13-05-2013 19:14:57

Asegúrate de que el conjunto de datos que está del lado del proveedor permanece cerrado.

¿Qué campos tienen la bandera pfInKey? Toma en cuenta que debe tener esa bandera activa (de la propiedad ProviderFlags) el campo de llave primaria de todos los conjuntos de datos (sean maestros o detalles), tanto del lado proveedor como del lado cliente. Y, en caso de capturar varios registros en memoria antes de enviarlos al servidor, debes alimentar ese campo (no esperar a que el servidor lo haga). ¿Cómo se llama el campo de llave primaria de la tabla detalle? Los demás campos no deben tener activa esa bandera.

Por otra parte, estando bien todo lo anterior, ya no sería necesaria la sentencia de asignación al campo IDStudy (TClientDataSet lo asignará de forma automática).

Saludos.

darkerviti 13-05-2013 19:51:25

Cita:

Empezado por Al González (Mensaje 460372)
Asegúrate de que el conjunto de datos que está del lado del proveedor permanece cerrado.

¿Qué campos tienen la bandera pfInKey? Toma en cuenta que debe tener esa bandera activa (de la propiedad ProviderFlags) el campo de llave primaria de todos los conjuntos de datos (sean maestros o detalles), tanto del lado proveedor como del lado cliente. Y, en caso de capturar varios registros en memoria antes de enviarlos al servidor, debes alimentar ese campo (no esperar a que el servidor lo haga). ¿Cómo se llama el campo de llave primaria de la tabla detalle? Los demás campos no deben tener activa esa bandera.

Por otra parte, estando bien todo lo anterior, ya no sería necesaria la sentencia de asignación al campo IDStudy (TClientDataSet lo asignará de forma automática).

Saludos.

He revisado las banderas y no estaba activa ninguna, he puesto pfInKey activa en las claves primarias tanto del maestro como del detalle y nada.


He hecho la prueba quitando el mastersource y con eso me funciona, la verdad es que no tiene mucho sentido eso, creo yo.

Al González 13-05-2013 21:05:46

Si gustas podemos verlo en conferencia por Skype. Tengo entendido que cuenta con "visor" de escritorio remoto. O si gustas haz una "prueba aislada" y anéxala en un mensaje para que los demás podamos mirar de cerca el problema.

Salgo por unas horas, saludos.

darkerviti 27-05-2013 13:29:06

Cita:

Empezado por Al González (Mensaje 460386)
Si gustas podemos verlo en conferencia por Skype. Tengo entendido que cuenta con "visor" de escritorio remoto. O si gustas haz una "prueba aislada" y anéxala en un mensaje para que los demás podamos mirar de cerca el problema.

Salgo por unas horas, saludos.

Siento no haber dado señales de vida, pero no he podido ponerme con esto durante estos días.

Retomo el hilo, ¿a qué te refieres con lo de prueba aislada? ¿os mando paso a paso pantallazos o algo así?

Un saludo.

Al González 27-05-2013 22:52:11

Cita:

Empezado por darkerviti (Mensaje 461303)
¿a qué te refieres con lo de prueba aislada?

Un nuevo programa con lo mínimo necesario para reproducir el error en la computadora de quien desee descargarlo para ver de cerca el problema. "Aislando" (separando) el problema de todo lo demás que contenga tu aplicación.

Saludos.

darkerviti 29-05-2013 10:42:11

Buenos días,

Parece que lo he resuelto a la tremenda, si cierro la conexión a la bbdd y la vuelvo a abrir, todo funciona.

LuisHatake 27-12-2017 20:30:56

Tengo el mismo problema
 
Cita:

Empezado por darkerviti (Mensaje 461450)
Buenos días,

Parece que lo he resuelto a la tremenda, si cierro la conexión a la bbdd y la vuelvo a abrir, todo funciona.

Hola a todos, te escribo porque me gustaría que compartieras tu solución. entiendo que cierras la conexión a la db pero en que momento la cierras y en que momento la vuelves abrir. también me gustaría saber si es lo único que modificas o si modificas algo mas de los demás componentes. tengo el mismo problema y me gustaría solucionarlo. espero su respuesta. muchas gracias. Yo utilizo postgresql y delphi 7. Tengo un dataSource enlazado al query y este a la conexión.

pkcito 28-12-2017 00:47:11

Transacciones
 
Entiendo que hay un problema de transacciones. No puedo asegurarlo sin tener más información.

Cuando se ejecuta el método ApplyUpdate del ClientDataSet los datos originales (los que se obtuvieron de la base de datos) y las modificaciones se empaquetan y se pasan al DataSetProvider. Dependiendo de su configuración, el DataSetProvider puede aplicar los cambios de dos formas: generando sentencias INSERT, UPDATE y DELETE (lo que hace por defecto) o actualizando los DataSet usados para obtener los datos. Asumo que la configuración del DataSetProvider no se ha modificado y se están generando sentencias INSERT, DELETE y UPDATE.

En el proceso que aplica los cambios se verifica si ya hay una transacción activa. Si la hay entonces no se hace StartTransaction ni Commit. Si no la hay entonces se hace StartTransaction y luego Commit. Está claro que en este caso hay una transaccíon activa y, si bien los cambios son aplicados en la base de datos, no son visibles fuera del contexto de la transacción activa. Al cerrar la conexión con la base de datos, y esto también depende de la configuración, la transacción activa es finalizada automáticamente con Commit.

Lo más probable es que sea el propio DataSetProvider el que inicia la transacción y la mantenga activa. Cuando el DataSetProvider no le pasa todos los registros disponibles al ClientDataSet (esto depende de la propiedad PacketRecords del ClientDataSet) entonces el DataSet que usa el DataSetProvider para obtener los datos permanece activo y su transacción asociada también.

Para solucionarlo de una forma más elegante (en vez de cerrar la conexión con la base de datos para forzar un Commit) me tienes que decir qué tecnología de acceso a datos estás usando. De todas formas creo que es una buena práctica usar dos transacciones (si se puede) o dos conexión con la base de datos: una de sólo lectura para mostrar registros y otra de lectura y escritura para modificarlos.

Espero que sea de ayuda.


La franja horaria es GMT +2. Ahora son las 11:10:52.

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