PDA

Ver la Versión Completa : Novato con DBExpress necesita entender como trabajan


apicito
10-12-2013, 12:12:00
He estado leyendo varios tutoriales sobre DBExpress pero no acabo de entender cual es la dinámica adecuada para trabajar con estos componentes. Sobre un ejemplo de formulario de edición real voy a explicar mis dudas haber si alguien me puede echar una mano para entenderlos.
En el formulario tengo cuatro conjuntos de componentes DBExpress, compuestos cada uno por TSQLQuery, TDataSetProvider, TClientDataset y TDataSource.
Un conjunto apuntando al registro que quiero editar "Expte" y los otros 3 para rellenar 3 DBLookupComboBox (Tipo,Zona y Estado).
En el onShow del formulario cargo los combos y dependiendo de una variable Modo [ (A) Append y (M) Edit ] edito un registro. Este es el código:
procedure TAveriasExpteEdit.UniFormShow(Sender: TObject);
begin

CargaTipos;
CargaZonas;
CargaEstados;

cdsExpte.Close;
queryExpte.CommandText := 'select * from AVEAVEDIA where AVEDIA_CODIGO=:codigo';
cdsExpte.Params.ParamByName('codigo').AsInteger := Codigo;
cdsExpte.Open;
case Modo of
'A' : cdsExpte.Append;
'M' : cdsExpte.Edit;
end;

end;
y cargo los datos de los combos:
procedure TAveriasExpteEdit.CargaTipos;
begin
cdsTipo.Close;
queryTipo.CommandText := 'select AVETIP_CODIGO,AVETIP_DESCRIP,AVETIP_ACTIVO '+
'from AVEAVETIP where AVETIP_ACTIVO=1 order by AVETIP_DESCRIP';
cdsTipo.Open;
end;
Cuestiones:
1. Está bien que las operaciones de apertura y cierre se hagan sobre el ClientDataset?
2. El CommandText y la carga de parametros (cdsExpte.Params.ParamByName('codigo').AsInteger := Codigo;) debe aplicarse sobre el TSQLQuery o sobre el clientDataSet?
3. En definitiva, como de correcto es el código que he puesto arriba?:
Un saludo.

Caminante
10-12-2013, 17:54:37
1. Está bien que las operaciones de apertura y cierre se hagan sobre el ClientDataset?


Si. El clientdataset se encargara de traer los datos mediante el proveedor.


2. El CommandText y la carga de parametros (cdsExpte.Params.ParamByName('codigo').AsInteger := Codigo;) debe aplicarse sobre el TSQLQuery o sobre el clientDataSet?



Nunca he usado commandtext desde un clientdataset pero siempre paso los parametros asi. No toco para nada el sqlquery.

Saludos

apicito
11-12-2013, 10:44:31
Gracias por tu respuesta. Lo he hecho así y funciona perfectamente.
Planteo o tra pregunta:
Para grabar los datos hago:
try
cdsExpte.Post;
cdsExpte.ApplyUpdates(0);
except
showmessage('Non se poido grabar');
Exit;
end;
ModalResult := mrOk;
No me graba nada. Ni cuando modifico un registro existente ni al crear uno nuevo.
En el caso de ser un alta, como cojo un autoincremnetal desde un generador para clave primaria?

apicito
11-12-2013, 12:32:35
No me graba nada. Ni cuando modifico un registro existente ni al crear uno nuevo.
En el caso de ser un alta, como cojo un autoincremnetal desde un generador para clave primaria?
Me auto respondo.
Si que graba, el problema esta en el autoinclemental. Como no he encontrado nada en DBExpress me he creado una función global y cojo el autoinckemental desde mi aplicación y no desde el generador de la base de datos:

function getAutoincremental : integer;
begin
result := Round((now() - 25569) * 86400);
end;
Hasta ahora había utilizado los componentes IbObjects que permite crear el auto incremental metiendole en la propiedad GeneratorLinks el valor adecuado:
QueryFras.GeneratorLinks.Clear;
QueryFras.GeneratorLinks.Text:='FRAS_CODIGO=FRAS';
donde FRAS es un generador de la base de datos.
Ahora voy a investigar como se manejan las transacciones con DBExpress. Por que noto que cuando vuelvo del formulario de edición y hago refresh del ClientDataSet del DBGrid no me muestra el valor que acabo de introucir, sino el de la anterior modificación, como si solo cerrara la transacción cuando destruyo el formulario.

Caminante
11-12-2013, 17:04:51
Hola

El metodo applyupdates devuelve el numero de errores encontrados al aplicar las actualizaciones. Mas o menos manejo las transacciones asi:

var
Td:TTransactionDesc;
Begin
td.TransactionID:=1;
td.IsolationLevel:=xilREADCOMMITTED;
SQLConnection1.StartTransaction(td);
if FVClientDataSet1.ApplyUpdates(0)=0then
SQLConnection1.Commit(td)
else
begin
SQLConnection1.Rollback(td);
ShowMessage('Hubo errores')
end;
end;

Applyupdates no muestra excepciones para mostrarlas debes manejar el evento reconcileerror.

Espero te sea util

Saludos

apicito
11-12-2013, 20:45:30
Gracias Caminante por la ayuda. Ahora veo como debo utulizar las transacciones.

bulc
20-02-2014, 21:16:49
He estado leyendo varios tutoriales sobre DBExpress pero no acabo de entender cual es la dinámica adecuada para trabajar con estos componentes. Sobre un ejemplo de formulario de edición real voy a explicar mis dudas haber si alguien me puede echar una mano para entenderlos.
En el formulario tengo cuatro conjuntos de componentes DBExpress, compuestos cada uno por TSQLQuery, TDataSetProvider, TClientDataset y TDataSource.
Un conjunto apuntando al registro que quiero editar "Expte" y los otros 3 para rellenar 3 DBLookupComboBox (Tipo,Zona y Estado).
En el onShow del formulario cargo los combos y dependiendo de una variable Modo [ (A) Append y (M) Edit ] edito un registro. Este es el código:
procedure TAveriasExpteEdit.UniFormShow(Sender: TObject);
begin

CargaTipos;
CargaZonas;
CargaEstados;

cdsExpte.Close;
queryExpte.CommandText := 'select * from AVEAVEDIA where AVEDIA_CODIGO=:codigo';
cdsExpte.Params.ParamByName('codigo').AsInteger := Codigo;
cdsExpte.Open;
case Modo of
'A' : cdsExpte.Append;
'M' : cdsExpte.Edit;
end;

end;
y cargo los datos de los combos:
procedure TAveriasExpteEdit.CargaTipos;
begin
cdsTipo.Close;
queryTipo.CommandText := 'select AVETIP_CODIGO,AVETIP_DESCRIP,AVETIP_ACTIVO '+
'from AVEAVETIP where AVETIP_ACTIVO=1 order by AVETIP_DESCRIP';
cdsTipo.Open;
end;
Cuestiones:
1. Está bien que las operaciones de apertura y cierre se hagan sobre el ClientDataset?
2. El CommandText y la carga de parametros (cdsExpte.Params.ParamByName('codigo').AsInteger := Codigo;) debe aplicarse sobre el TSQLQuery o sobre el clientDataSet?
3. En definitiva, como de correcto es el código que he puesto arriba?:
Un saludo.
¿Usas Firebird?