Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 12-01-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
Componente para actualizar datos de un query...

Hola a tod@s,

en una aplicación en D7 y SQL2005 hago la siguiente consulta :

Código SQL [-]
select p.cdgo, p.nmroorden, p.cdgotop, p.fecha, t.nmbrecmplto, pl.cdgoparte, pl.cdgolin, pl.produc, pl.cntctos, pl.vntas
from tblcbcra p inner join tbldtlle pl on (pl.cdgoparte = p.cdgo) inner join
  trbjdres t on (t.cdgo = p.cdgotop)
where (p.nmroorden = XXXXXXX and p.fecha = '14/10/2009')
order by t.nmbrecmplto

los datos obtenidos se muestran en un dbgrid, hasta ahí todo es ok, pero ahora me piden poder modificar los datos de un par de esas columnas (pl.cntctos y pl.ventas) y que "sea en un formato similar al excel (líneas, columnas, cursor, etc...) para agilizar la modificación de esos datos" ya que con dbedit nos les parece nada "friendly"

La duda es que no tengo nada claro que componente utilizar ni por dónde empezar, agradecería vuestros consejos y ayuda al respecto.

Muchas Gracias y Saludos.
__________________
Toni | blog
Responder Con Cita
  #2  
Antiguo 13-01-2010
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Hola Toni.
¿No puedes hacerlo directamente sobre el DBGrid?

Al no ser una tabla, sino una consulta, tal vez deberías utilizar TClentDataset. De esa forma al modificar los datos sobre el ClientDataSet, porteriormente deberás traspasar esas modificaciones a tu tabla de la Base de Datos.

No se si me explico...
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 13-01-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
Gracias por la respuesta Neftali,

estaba planteandome esa alternativa pero no tengo claro cómo hacer que posteriormente se actualicen los datos de una sola tabla. La qry está compuesta de 3 tablas (2 de ellas son cabeceras-lineas) y sólo se han de modificar los datos de las líneas.

En qué evento debería lanzar el upgrade?
Debería actualizar los datos en cada línea que se modifique?

No lo tengo nada claro
__________________
Toni | blog
Responder Con Cita
  #4  
Antiguo 13-01-2010
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por tgsistemas Ver Mensaje
En qué evento debería lanzar el upgrade?
Debería actualizar los datos en cada línea que se modifique?
La actalización de datos puedes lanzarla cuando tú lo necesites; Hay casos en que es necesario que los cambios se realicen de forma instantánea en la Base de Datos, y en cambio otras veces es necesario hacerlos todos al final.

Imagina el caso de una factura, en que un usuario debe poder cambiar cosas y al final "validarla toda" o "anularla toda"; Con esa premisa esperarías al final a realizarlos todos.

Para "volcar" los cambios a Base de Datos, supongo que lo más sencillo es en el AfterPost del TClientDataSet (o similar) si lo vas a hacer inmediato; En el caso de realizarlos al final es mucho más sencillo.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #5  
Antiguo 13-01-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
Gracias Neftali,

ya tengo el TClientDataSet (con un TDataSetProvider) mostrando los datos en un DBGrid con todos las validaciones, formatos y restricciones necesarias, es decir, todas las columnas en ReadOnly excepto las que pueden modificar.

Ahora viene el tema de la actualización en la bbdd

Hay alguna forma de saber los registros que se han modificado para así sólo actualizar éstos o se ha de hacer update de todos los registros iniciales ?? Es decir, si la qry devolvió 10 registros y se han modificado (en TClientDataSet) sólo 2... se ha de hacer update de los 10 o se puede hacer sólo de los 2??

Existe algo del tipo for update o inserted y/o deleted como en sql ??

Muchas Gracias por ayuda
__________________
Toni | blog
Responder Con Cita
  #6  
Antiguo 13-01-2010
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por tgsistemas Ver Mensaje
Ahora viene el tema de la actualización en la bbdd

Hay alguna forma de saber los registros que se han modificado para así sólo actualizar éstos o se ha de hacer update de todos los registros iniciales ?? Es decir, si la qry devolvió 10 registros y se han modificado (en TClientDataSet) sólo 2... se ha de hacer update de los 10 o se puede hacer sólo de los 2??

Existe algo del tipo for update o inserted y/o deleted como en sql ??
No hace falta hacerlo todo.
Podrías hacerlo manualmente, marcando tú los registros que se han modificado. Por ejemplo, si utilizas un campo de interno de Modificado y cada vez que guardas un registro lo activas a True, al final basta recorrer y sólo generar las SQL (upates) para aquellos que se han modificado.

De todas formas, TClientDataset ya posee propiedades para controlar esto.
Revisa en la ayuda la propiedad ChangeCount, Delta, ChangeLog,...
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #7  
Antiguo 13-01-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
Neftali,

perdona pero he leido las propiedades que comentas y algunos hilos del foro sobre TClientDataSet y he estado haciendo algunas pruebas, todas con resultado nefasto

En un button he puesto el siguiente código :

Cita:
if (cdsPARTESDATOS.ChangeCount > 0) then
cdsPARTESDATOS.ApplyUpdates(-1);
según he leído el propio ClientDataSet hace la actualización en la tabla que corresponda, cosa que me sorprende bastante !!!

El resultado que obtengo es un error no es posible encontrar el registro, no se especificó ninguna clave así que en el provider he puesto la propiedad updatemode=upWhereKeyOnly pero no tengo claro dónde especificar los campos que forman la clave para actualizar la tabla detalle que es la única que se actualizará.

Gracias por la paciencia....
__________________
Toni | blog
Responder Con Cita
  #8  
Antiguo 13-01-2010
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por tgsistemas Ver Mensaje
...según he leído el propio ClientDataSet hace la actualización en la tabla que corresponda, cosa que me sorprende bastante !!!
Hola.
Que no te resulte extraño, así es como funciona el TClientDataset (es que en muy bueno).

Si has accedido a una tabla, él sólo, es capaz cuando tú se lo digas (ApplyUpdates) de volcar todos los cambios (Updates/Insert/Delete) a la tabla de Base de Datos.
El problema es que en tu caso, los datos no provienen de una tabla, sino de una consulta con JOIN's, de ahí que no se puedan realizar las actualizaciones de forma auomática y seguramente debas acabar haciéndolas de forma manual.

Mi idea, es que puedas aprovechar (si es posible) la información que guarda TClientDataset para saber qué registros se han modificado y así saber cueles debes actualizar (esto es una idea, ya que nunca he probado a acceder a esa información).

Si no es posible, puedes utilizar el método "manual" (campo Modificado) que he comentado antes.

Un saludo.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #9  
Antiguo 13-01-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
Neftali,

y si hiciera la consulta original de este modo ??
Cita:
select PL.CDGOPARTE, PL.CDGOLIN, PL.TPLGIA, PL.H1_E, PL.H1_S, PL.H2_E, PL.H2_S, PL.HT,
PL.PRODUC, PL.CNTCTOS, PL.VENTAS,
P.CDGO, P.NMROORDEN, P.CDGOTOP, P.FECHA, T.NMBRECMPLTO, P.ACTIVO

from tblcbcra p, tbldetalle pl, trbjdres t

WHERE (
(pl.cdgoparte = p.cdgo) AND
(t.cdgo = p.cdgotop) AND
(P.NMROORDEN = XXXXXXX AND P.FECHA = '14/10/2009')
)
order by T.NMBRECMPLTO
de este modo no hay ningún join por el medio y podría definir la clave principal de la tabla tbldetalle para hacer el update automáticamente ??
__________________
Toni | blog
Responder Con Cita
  #10  
Antiguo 14-01-2010
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Creo que no va a funcionar Toni. N es una Join, pero es un producto cartesiano.
El problema no está en la JOIN es si, sino en mezclar datos de diferentes tablas en un DataSet.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #11  
Antiguo 14-01-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
He buscado información al respecto, he visto varios casos de qry de más de una tabla
Por lo que he entendido, el update resultante se gestiona en función de algunas propiedades de los campos en el DataSet original mediante banderas que se parametrizan en ProviderFlags.
Los campos que se actualizarán con la propiedad pfInUpdate, los campos implicados en el where con la propiedad pfInWhere y los de clave principal con pfInKey.

Siguiendo esas premisas he parametrizados todos los campos y me gustaría saber si conoces algún método para que pueda ver la sentencia sql del update resultante.

En la qry original he identificado todos los campos con su nombre correcto de tabla, sin utilizar alias para intentar evitar problemas de identificación de éstos.

El error que produce ahora al realizar el ApplyUpdates es El nombre de la columna CDGOPARTE no es válido y El nombre de la columna CDGOLIN no es válido, ambos campos son la clave principal de la tabla tbldetalle que és la que se debe actualizar.

Es posible que el problema venga por tratarse de tablas Maestro/Detalle ??

Muchas gracias por la ayuda
__________________
Toni | blog
Responder Con Cita
  #12  
Antiguo 14-01-2010
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por tgsistemas Ver Mensaje
...y me gustaría saber si conoces algún método para que pueda ver la sentencia sql del update resultante.
Lo siento Toni.
Nunca he llegado a este punto y creo que no debes intentar actualizar con el ApplyUpdates.

Por internet he encontrado esto, que viene a ser más o menos lo que tiene más lógica:

ApplyUpdates cannot handle updates to a join. You need to create a
BeforeUpdateRecord event handler for the DSP and create and execute the
UPDATE statements for each table.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #13  
Antiguo 15-01-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
Neftali,

al final lo he resuelto siguiendo tus indicaciones, creando un campo actualizado que voy marcando al guardar los cambios en el ClientDataSet, en un button he creado un proceso que recorre el ClientDataSet y lanza un qry de update en función del valor del campo actualizado. Hasta aquí todo funciona perfectamente y realiza los updates correctamente

El problema que tengo ahora es que en el DBGrid asociado al ClientDataSet se pueden añadir líneas y quisiera eliminar esa opción, es decir, que no puedan añadir ninguna línea, pero no sé cómo hacerlo ??

Muchas Gracias
__________________
Toni | blog
Responder Con Cita
  #14  
Antiguo 15-01-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
Perdón, no me expliqué demasiado bien...

lo que quiero es no permitir insert ya sea bloqueando el DBGrid que muestra los datos, en ClientDataSet o en el Provider.

Sorry por la confusión generada
__________________
Toni | blog
Responder Con Cita
  #15  
Antiguo 15-01-2010
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Prueba a poner en el OnNewRecord del ADOQuery:

Código Delphi [-]
  ADOQuery.Cancel;
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #16  
Antiguo 15-01-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
no utilizo ADOQuery...

tengo los siguientes componentes con esas conexiones :
- RxQuery que busca los datos originales conectando con bde al sqlserver
- DataSetProvider cuyo DataSet es el RxQuery
- ClientDataSet con ProviderName = DataSetProvider
- DataSource con DataSet = ClientDataSet
- DBGrid con DataSource = DataSource

y un TQuery (conectado vía bde) que lanza el update cuando es llamado.

En el DBGrid, si bajas una línea al final (con el cursor), intenta añadir una línea en el ClientDataSet y eso es lo que quiero evitar.

Saludos y Gracias
__________________
Toni | blog
Responder Con Cita
  #17  
Antiguo 15-01-2010
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Bueno me refería a la fuente de datos.
En tu caso al TClientDataset
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #18  
Antiguo 15-01-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
Neftali,

tras bastante código añadido para restricciones, totales, etc... funciona todo perfectamente con la solución del campo "actualizado" y lanzando el update mediante un button, por lo que se puede cerrar el hilo

Muchas Gracias por la ayuda y la paciencia!!!!

P.D.: el componente ClientDataSet realmente está muy, muy bien para otras forms dónde actualizan datos de una sola tabla
__________________
Toni | blog
Responder Con Cita
Respuesta



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
La mejor tecnica para actualizar datos NickName Firebird e Interbase 1 20-06-2011 15:47:08
Ayuda por favor para correr un query en Delphi a una base de datos en Mysql charlyfitlh MySQL 10 01-11-2007 20:28:49
Problema con query para una base de datos de Access omarifr SQL 3 27-07-2007 00:36:50
Problemas para actualizar datos Nelly Varios 2 20-11-2006 14:07:44
Actualizar datos con componente jvDBComboBox rochi Conexión con bases de datos 0 15-02-2005 17:35:20


La franja horaria es GMT +2. Ahora son las 02:34:13.


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