Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   eliminar registros del ClientDataSet (https://www.clubdelphi.com/foros/showthread.php?t=73756)

_CALI 14-05-2011 17:56:10

eliminar registros del ClientDataSet
 
hola amigos una pregunta
tengo lo siguiente:


-un Query 'SELECT ID, CAMPO1, CAMPO2 FROM TABLA'
añado los campos persistentes

en el campo ID establesco prodiverFlags a: [pfInUpdate,pfInWhere,pfInKey]
en el campo CAMPO1 providerFlags a: [pfInUpdate]
en el campo CAMPO2 providerFlags a: [pfInUpdate]

- un DataSetProvider asociado al Query
en la propiedad UpdateMode = upWhereKeyOnly

-un ClientDataset asociado al Proveedor


pues bien:

abro dos formularios con el clientDataSet

cuando modifico un valor en el campo1 o campo2 todo funciona bien ,
pero cuando elimino y registro y luego voy al otro formulario y lo elimino me da error que "no se encontro el registro para su actualizacion o algo asi"

uso lo siguiente:


Código Delphi [-]
 
ClientDataSet.Delete;
  ClientDataSet.ApplyUpdates(0);





como podria solucionarlo Gracias!!:)

Al González 16-05-2011 18:26:34

Cita:

Empezado por _CALI (Mensaje 400036)
pero cuando elimino y registro y luego voy al otro formulario y lo elimino me da error que "no se encontro el registro para su actualizacion o algo asi"

¿Podrías detallar más esta parte? No me queda claro cuál es el mensaje de error y tampoco eso de "elimino y registro y luego...".

Un poco más de dedicación y calma al escribir estos mensajes, empleando comas y acentos donde corresponda, no te vendría mal _CALI. Demuestra el respeto que tienes por quienes te queremos ayudar.

:)

_CALI 19-05-2011 06:23:45

gracias por mostrar interes y discúlpa por no explicarme bien.
 
estoy haciendo un proyecto MDI para que pueda ser usado en red por varios usuarios; Mi proyecto consta de los siguientes elementos:
  • Un formulario principal (padre) estableciendo su propiedad formStyle a MDIForm y con un TMainMenu que llama a un formulario (hijo) para el control de Artículos.
  • Un formulario (hijo) con su propiedad formStyle a MDIChild, en este formulario es donde controlo los registros de los artículos, posee un ClientDataSet que esta conectado a un DataSetProvider que se encuentra en el Modulo de Datos.
  • Un Módulo de Datos que contiene los siguientes componentes:
1. Un ADOConnection para conectarme a SQLServer 2005
2. Un DataSetProvider asociado al ADOQuery
3. Un ADOQuery que en su propìedad SQL tengo la instrucción:

'SELECT ID_ARTICULO, DESCRIPCION, PRECIO FROM ARTICULOS';


Ademas añado los campos persistentes en el ADOQuery, para poder configurar la propiedad ProviderFlags de cada campo


Nota: investiguando, di con la propiedad de TField: "ProviderFlags" y UpdateMode de DataSetProvider, que configuran como el DataSetProvider debe ejecutar las intrucciones SQL: UPDATE, DELETE O INSERT.

Lo que pienso; y si es que estoy mal, tambien me gustaria una orientación al respecto, es que cuando no se configuran los providerFlags de cada campo y UpdateMode del DatasetProvider; solo se puede modificar un registro por ves, es decir que el registro no acepta concurrencia, hice ciertas pruebas abriendo dos formularios de Articulos con los valores por defecto de las propiedades antes mensionadas, al momento de modificar un registro del formulario 2 que estaba siendo usado en el formulario 1, me daba como error "Record no found or changed by another user", pero estableciendo dichas propiedades como mas adelante detallo ya no me daba ese error.


configuro la propiedad de cada campo de ADOQuery ProviderFlags de la siguiente manera:

en el campo ID_ARTICULO establesco prodiverFlags a: [pfInUpdate,pfInWhere,pfInKey]

en el campo DESCRIPCION providerFlags a: [pfInUpdate]
en el campo PRECIO providerFlags a: [pfInUpdate]

por último, en el DataSetProvider, en la propiedad UpdateMode establesco a : upWhereKeyOnly


pues bien:

abro dos formularios de artículos

cuando modifico un registro en el formulario 1 y sin aplicar los cambios voy al formulario 2 y modifico el mismo resgistro pero esta vez si aplicando los cambios no me da el error de "Record no found or changed by another user"
todo bien; Pero cuando elimino un registro en el formulario 1 y luego trato de modificar el mismo registro en el formulario 2, me aparece el siguiente mensaje de error: "Record no found or changed by another user"





espero haberme explicado bien

Muchas Gracias como siempre!!

ecfisa 19-05-2011 06:39:34

Cita:

cuando modifico un registro en el formulario 1 y sin aplicar los cambios voy al formulario 2 y modifico el mismo resgistro pero esta vez si aplicando los cambios no me da el error de "Record no found or changed by another user"
todo bien; Pero cuando elimino un registro en el formulario 1 y luego trato de modificar el mismo registro en el formulario 2, me aparece el siguiente mensaje de error: "Record no found or changed by another user"
Si tenés un control de concurrencia optimista me parece que es el comportamiento esperado. Ya que en el primer caso el supuesto primer usuario todavía no ha confirmado los cambios, en cambio en el segundo caso si el registro ya ha sido eliminado, lógicamente debe notificarse.

Según he leido podés elegir el tipo de comportamiento de SQL Server: Aislamiento de instantánea de SQL Server 2005 .

Un saludo.

_CALI 19-05-2011 18:16:25

me serviria de mucho ver como genera el DataSetProvider las sentencias SQL INSERT UPDATE O DELETE GRACIAS!!

Al González 20-05-2011 08:53:29

Hola _Cali.

Eso de querer modificar después de borrar tiene algo de metafísico. :p

De cualquier manera, creo que leer en su totalidad este hilo te ayudará a compreder mejor varias de las cosas que estás manejando.

Incluso te servirá para resolver esta inquietud:
Cita:

Empezado por _CALI (Mensaje 400665)
me serviria de mucho ver como genera el DataSetProvider las sentencias SQL INSERT UPDATE O DELETE GRACIAS!!

Una despedida al llegar.

Al González. :)

_CALI 21-05-2011 06:33:47

jeje
 
claro que no pretendo modificar algo que no existe.

por ejemplo si tenemos un tabla con los siguientes registros:

articulos
id_articulo nombre
a01 arroz
a02 azucar
a03 fideos

si ejecuto la siguiente instruccion sql:


Código SQL [-]
UPDATE ARTICULOS SET NOMBRE = 'REFRESCO'
WHERE ID_ARTICULO = 'A05'





no muestra ningun error verdad?, solo mi inquietud porque el datasetProvider muestra que el registro A05 ya no existe o otro usuario lo cambio


de todas maneras lo resolvi implementando el evento OnUpdateError del provedor



Código Delphi [-]
if UpdateKind in [ukModified, ukDeleted] then
begin
Resolve := rrIgnore;
end;




te todas maneras seguire investigando, gracias de nuevo al_gonzales por responder:)

_CALI 21-05-2011 09:21:27

Hola!
 
Al_Gonzales:
estuve viendo el hilo que me sugeriste y me parecio muy interesante, siguiendo los pasos de depuración, como mostrabas en el hilo, pude aclarar varias dudas, pero saltaron otras mas.

Primero, la propiedad UpdateMode de mi proveedor está establecida con upWhereKeyOnly,
el campo de busqueda para el proveedor es mi ID que tiene la bandera pfInKey, siguiendo las recomendaciones que dabas, añadí en la ventana (watches) una nueva propiedad para observación Provider.UpdateMode,
ejecuto el programa en depuración y la propiedad añadida a (watches) se establece a upWhereKeyOnly, mas no cambia a upWhereAll, es mas, mire el valor de SQL.Text que se muestra en código mas abajo y efectivamente dice: delete from articulos '#$D#$A'where id_articulo = '#$D#$A', es decir que la consulta en la clausula WHERE no anida los demas campos con el operador AND, solo hace referncia al campo de búsqueda id_articulo (ID) que esta con pfInKey, cosa que me parece perfecto.

Código Delphi [-]
 
procedure TSQLResolver.DoExecSQL(SQL: TWideStringList; Params: TParams);
var
  RowsAffected: Integer;
begin
  RowsAffected := (Provider.DataSet as IProviderSupport).PSExecuteStatement(SQL.Text, Params);
  if not (poAllowMultiRecordUpdates in Provider.Options) and (RowsAffected > 1) then
  begin
    (Provider.DataSet as IProviderSupport).PSEndTransaction(False);
    Provider.TransactionStarted := False;
    DatabaseError(STooManyRecordsModified);
  end;
  if RowsAffected < 1 then
    DatabaseError(SRecordChanged);
end;

me di cuenta que error salta despues de la linea:
Código Delphi [-]
 
if RowsAffected < 1 then 
   DatabaseError(SRecordChanged);
claro si es que el otro usuario ya lo borró previamente.

Bueno lo que pienso, es que por parte del rervidor (SQLServer), el proveedor recibe la notificación que ningun registro existe con ese valor, si es asi pues todo ya tiene lógica


en ese caso podria ignorar la actualizacion si esque RowsAffected es < 1 cierto?

como podria hacerlo???
lo único que me ha funcionado hasta ahora fue implementar el evento OnUpdateError de la siguiente manera:

Código Delphi [-]
if UpdateKind in [ukModify, ukDelete] then
   begin
     Response := rrIgnore;
   end;

pero como bien sabes se puede resolver un problema de mil maneras, la diferencia está en la manera mas apropiada!


Gracias denuevo, si veo algo nuevo al respecto lo comunicare


Saludos!!!:)


La franja horaria es GMT +2. Ahora son las 11:15:06.

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