PDA

Ver la Versión Completa : Insert con ClientDataSet


Rockin
16-06-2008, 16:06:53
Hola amigos, tengo un pequeño problema y no se como solucionarlo, tengo el siguiente codigo.


datDatosRemoto.FIBClientDataSetTurnos.Open;
datDatosRemoto.FIBClientDataSetTurnos.Insert;
datDatosRemoto.FIBClientDataSetTurnos.FieldByName('tipo_turno').AsString:= txtTurno.Text;
datDatosRemoto.FIBClientDataSetTurnos.FieldByName('horas').AsDateTime:= strtotime(txtHoras.Text);
datDatosRemoto.FIBClientDataSetTurnos.Post;


Donde inserto registros, el problema es que al insertar y comprobar el DBGrid asociado me aparece en este, pero al salir de la aplicacion y volve a entrar ya no me aparece, y en la BD no queda grabado ningún registro. Lo mismo me ocurre al modificar datos.

¿Que estoy haciendo mal?..
Saludos

enecumene
16-06-2008, 16:13:43
Hola, Para grabarlo en la base de datos debes usar:

datDatosRemoto.FIBClientDataSetTurnos.ApplyUpdates(-1);

Eso va luego del post.

Saludos.

Rockin
16-06-2008, 16:29:39
Tengo puesto en el evento AfterPost del CDS, ApplyUpdates(0), y como te digo me guarda los cambios si lo vuelvo a consultar en el momento, pero al salir y entrar en la aplicación ya no sale. Es como si lo mantuviera en memoria, o yo que se. Voy a probar como me dices, de todas formas.

Saludos.

Al González
16-06-2008, 17:28:15
¡Hola!

Tengo puesto en el evento AfterPost del CDS, ApplyUpdates(0), y como te digo me guarda los cambios si lo vuelvo a consultar en el momento, pero al salir y entrar en la aplicación ya no sale. Es como si lo mantuviera en memoria, o yo que se. Voy a probar como me dices, de todas formas.

Saludos.
Lo que haces está bien, si el objetivo es que cada registro guardado se refleje de inmediato en la base de datos. Lo que puede estar sucediendo es que en ese momento tengas abierta una "transacción", la cual no es "cometida" (confirmada) antes de cerrar el programa y por lo tanto se esté "revirtiendo" (rollback).

Te sugiero revisar cómo estás manejando las transacciones en tu programa.

Saludos.

Al González. :)

Rockin
16-06-2008, 18:36:36
He estado buscando y tengo entendido que el DataSetProvider en el Servidor de Capa Intermedia, es el encargado de activar las transacciones asociadas al DataSet. A lo mejor me estoy equivocando y tengo que llamarla yo, o confirmarla como me comentas.

Seguire con el tema a ver si doy con ello.

Al González
17-06-2008, 03:11:21
¡Hola!

...tengo entendido que el DataSetProvider en el Servidor de Capa Intermedia, es el encargado de activar las transacciones asociadas al DataSet...
En efecto, eso hace el componente TDataSetProvider cuando la conexión no tiene una transacción activa en ese momento. Es decir, si el programa no ha empezado una transacción explícitamente, el componente proveedor la establece y cierra cuando aplica las actualizaciones.

Esto fue lo que me llevó a pensar que tal vez tu programa sí está abriendo una transacción antes de la llamada a ApplyUpdates (probablemente es algo que haga de manera predeterminada alguno de los componentes de conexión que estás usando).

Aquí el código que ejecuta el proveedor en la capa intermedia (unidad Provider.pas):


function TDataSetProvider.InternalApplyUpdates(const Delta: OleVariant; MaxErrors: Integer;
out ErrorCount: Integer): OleVariant;
begin
CheckDataSet;
FTransactionStarted := not IProviderSupport(DataSet).PSInTransaction;

// Sólo si no hay ya transacción activa, el componente proveedor abrirá una
if FTransactionStarted then
IProviderSupport(DataSet).PSStartTransaction;
try
CheckResolver;
Resolver.FUpdateTree.InitData(DataSet);
try
Result := inherited InternalApplyUpdates(Delta, MaxErrors, ErrorCount);
finally
Resolver.FUpdateTree.InitData(nil);
end;
finally
if FTransactionStarted then
IProviderSupport(DataSet).PSEndTransaction((ErrorCount <= MaxErrors) or (MaxErrors = -1));
end;
end;


Espero te sea de utilidad, no dejes de retroalimentar el hilo.

Al González. :)

Rockin
17-06-2008, 13:30:12
Gracias por tu interés pero estoy desesperado, he mirado en diez millones de foro, he probado de todas las maneras posible pero nada, en fin voy a probar con SQL Server, a ver si el problema es de los componentes de Firebird, por decir algo.

Rockin
18-06-2008, 08:58:56
No se si tendré algo mal declarado en las propiedades del Provider, ClientDataSet o yo que se.

Saludos.

Rockin
14-07-2008, 17:02:46
Sigo liado con el tema este, no tengo cojones de realizar cambios en la BD.Lo he intentado multitud de formas y nada.

Realizo el ApplyUpdate(0) despues del POST, y me guarda los cambios, ya que al realizar un consulta y mostrarlo en un DBGrid me sale modificado, pero al salir de la aplicación los cambios no se reflejan en la tabla de la BD.

¿Alguien puede ayudarme, please?

enecumene
14-07-2008, 17:08:24
Hola, debes realizar el commit al FIBConnection para que se grabe en la base de datos.

DatosRemotos.FConnection1.Commit;

Saludos.

Rockin
14-07-2008, 19:16:51
¿que componente es FIBConnection? No lo tengo declarado

enecumene
14-07-2008, 19:21:20
¿que componente es FIBConnection? No lo tengo declarado

:D perdón, realmente no sé como se llama el componente para conectar a la base de datos, en el caso de ADO sería ADOConnection, el de ZEOS ZConnection, no sé el de FIBPlus entonce asumí que se llamaría así.

Saludos.

Rockin
14-07-2008, 19:54:08
NO tiene ningun componente tipo connection como el que comentas.

Gracias por tu ayuda

enecumene
14-07-2008, 19:55:58
NO tiene ningun componente tipo connection como el que comentas.

Gracias por tu ayuda

A ver, por que creo que sí lo tiene, ¿con qué componentes ligas la base de datos? (No la tabla, el .FDB), ¿tu base de datos no es Firebird?.

Saludos.

Rockin
15-07-2008, 10:21:13
Para conectar con la BD uso el FIBDataBase.

¿Los campos persistentes hay que añadirlos siempre?

Saludos.

enecumene
15-07-2008, 13:52:34
Para conectar con la BD uso el FIBDataBase.

¿Los campos persistentes hay que añadirlos siempre?

Saludos.

Pues eso, para grabar:

FIBDataBase.Commit;

para echar para atrás la transacción:

FIBDataBase.RollBack;

Saludos.

Rockin
15-07-2008, 13:57:16
Pero en la aplicación cliente no tengo el FIBDataBase, el componente está en el servidor de capa intermedia, con su Transacción correspondiente, la cual teoricamente la inicia y finaliza el DataSetProvider, pero no tengo cojones, y me estoy desesperando mucho.

Seguire buscando, gracias.

Saludos.

enecumene
15-07-2008, 15:17:26
Pero en la aplicación cliente no tengo el FIBDataBase, el componente está en el servidor de capa intermedia, con su Transacción correspondiente, la cual teoricamente la inicia y finaliza el DataSetProvider, pero no tengo cojones, y me estoy desesperando mucho.

Seguire buscando, gracias.

Saludos.

Bueno amigo, ¿y qué componentes usas en el cliente?, porque el cliente es el que tiene la transacción activa, así que el cliente debe hacer el commit no el servidor.

Saludos.

Rockin
15-07-2008, 15:57:14
Esto es lo que uso:

Servidor Capa Intermedia

FIBDataBase + FIBDataSet + FIBTransaction + FIBDataSetProvider

Aplicación Cliente

FIBClientDataSet conectado a su Correspondiente FIBDataSetProvider a través de un SocketConnection.

Creo que el que se encarga de iniciar y finalizar la transaccion es el DataSetProvider del servidor de capa intermedia, no en el cliente.

Así es como lo tengo montado, las consultas perfectas y muy rapidas, pero la inserción, modificación e eliminación de registros, me lo hace en memoria pero no lo termina de actualizar a la BD, tengo puesto en el evento afterpost del ClientDataSet el ApplyUpdate(0) famoso.

Saludos.

enecumene
15-07-2008, 16:04:59
Efectivamente amigo, es lo que trato decirle, el cliente debe realizar el commit al servidor a traves del socket como dices, solo asi los datos se quedarán grabados en la base.

Ejemplo:

//insercion de datos
try
....
FIBClientDataSet.ApplyUpdates(-1);
FIBDatabase.Commit;
except
//mensajes de error
FIBDatabase.rollback;
end;

sólo así te va a grabar los datos, tal vez me pueda equivocar :p, pero estoy seguro que ese es el problema.

Saludos.

Rockin
15-07-2008, 16:16:18
Es que en el cliente no está declarado el FIBDataBase,está en el servidor de capa intermedia por lo que no puedo realizar el Commit en la base de datos.

En la respuesta de Al González anterior, explica que el DataSetProvider es el encargado de activar las transacciones asociadas al DataSet en cuestión.

Seguire mirando. Gracias.

Al González
15-07-2008, 16:36:31
...En la respuesta de Al González anterior, explica que el DataSetProvider es el encargado de activar las transacciones asociadas al DataSet en cuestión...
¡'pérate, 'pérate! Repito lo que dije:
En efecto, eso hace el componente TDataSetProvider cuando la conexión no tiene una transacción activa en ese momento. Es decir, si el programa no ha empezado una transacción explícitamente, el componente proveedor la establece y cierra cuando aplica las actualizaciones...

Todo parece indicar que ya hay una transacción abierta. Lo primero que habría que investigar es cómo se está abriendo esa transacción para optar por una de dos soluciones:

1. Evitar que haga ese "start transacción".

2. Hacer que tu módulo de datos de la capa intermedia exporte un método que te permita llamar al método "Commit" (o como se llame) de tu componente Database.

Es usual que la capa intermedia exporte algunos métodos (procedimientos) para facilitar que los programas cliente hagan ciertas operaciones contra la base de datos.

Saludos.

Al.

enecumene
15-07-2008, 16:55:02
Al lo ha explicado mejor que yo, no creo que exista algo más claro que eso :)

Saludos.

Rockin
15-07-2008, 16:55:21
Si lo explica de puta madre, pero no lo veo.

Yo tengo un FIBTransaction declarado, lo pongo active := False, para que el DataSetProvider la active? o que hago?

En breves habrá un forero menos porque me voy a suicidar.

enecumene
15-07-2008, 16:58:15
...
En breves habrá un forero menos porque me voy a suicidar.

Hombre, no seas tan drástico :p, eso es lo menos que queremos, venga pasate a la taberna y bebamos unas chelas ;).

Saludos.

Rockin
15-07-2008, 17:38:47
Lo conseguí como bien decia el ilustrisimo señor Al González, he tenido que realizar lo siguiente:

procedure TPruebaFirebird.FIBDataSetProviderTurnosAfterApplyUpdates(
Sender: TObject; var OwnerData: OleVariant);
begin

if FIBTransactionTurnos.InTransaction then
begin
FIBTransactionTurnos.Commit;
end;
end;

Gracias a vosotros y el magnifico libro la cara oculta de delphi 6 lo conseguí.

Repito ¡GRACIA!