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)
-   -   Delphi 2007 - Maestro detalle TIBDataSet+TDataSetProvider+TClientDataSet (https://www.clubdelphi.com/foros/showthread.php?t=58020)

GuerreroDelphi 05-07-2008 01:23:20

Delphi 2007 - Maestro detalle TIBDataSet+TDataSetProvider+TClientDataSet
 
Hola, amigos del foro:
Busco la corrección a un problema que no he podido solucionar de ninguna manera.
Tengo una aplicación en Delphi 5, y en ella manejo una relación maestro detalle con componentes IBExpress, para acceso a FireBird 2.1, así
DtsMaestro --> TIBDataSet
PrvMaestro --> TDataSetProvider
CdsMaestro --> TClientDataSet
DscMaestro --> TDataSource

DtsDetalle --> TIBDataSet
PrvDetalle --> TDataSetProvider
CdsDetalle --> TClientDataSet

DtsMaestro.SELECTSql.Text:= 'SELECT * FROM DOCUMENTOS'
DtsDetalle.SELECTSql.Text:= 'SELECT * FROM DOCUMENTOSDETALLE'

En tiempo de diseño, establezco la relación maestro-detalle sobre los componentes TClientDataSet, de la siguiente manera:
CdsDetalle.MasterSource = DscMaestro
CdsDetalle.MasterFields = 'Indice' (que es el campo llave primaria en la tabla DOCUMENTOS)
CdsDetalle.IndexFieldNames = 'DocumentoIndice' (campo que liga con la llave primaria 'Indice' del maestro)
... y todo funciona correctamente.

El inconveniente se presenta ahora, que he actualizado a Delphi 2007: cuando intento abrir el CdsDetalle, me arroja el error 'Field "DOCUMENTOINDICE" not found, aún cuando todo está bien parametrizado.
Haciendo otras pruebas, he notado que tengo este problema, sólo cuando utilizo TIBDataSet, porque si uso, por ejemplo TIBTable, funciona perfecto.
¿Cómo soluciono esto? ¿Existen problemas con el componente TIBDataSet incluido en Delphi 2007?
Agradezco a quien me pueda colaborar.

Al González 05-07-2008 07:12:58

¡Hola!

Lo planteado me despierta un par de sospechas. Por un lado el mensaje de error que dices arroja. ¿Podrías mostrárnoslo íntegro? (tip: en las ventanas de error de Delphi puedes usar Ctrl+C ;)).

Por otra parte, parece que a la segunda sentencia le falta el parámetro con el que se logra el filtrado.

Código SQL [-]
SELECT * FROM DOCUMENTOSDETALLE Where DocumentoIndice = :DocumentoIndice

NOTA: Con respecto a esto último, hay que tener presente que el componente TClientDataSet nativo da por hecho que el parámetro usado lleva el mismo nombre que el campo indicado en IndexFieldNames. Por lo menos con el TClientDataSet de Delphi 7, la existencia del parámetro con el mismo nombre es condicionante para establecer de esta forma la relación maestro-detalle.

Esperamos tu retroalimentación.

Saludos.

Al González. :)

GuerreroDelphi 05-07-2008 20:41:48

Gracias, Al Fernández.
1. El mensaje que arroja es exactamente: 'Field "DOCUMENTOINDICE" not found', nada más.
2. Añadí en parametro del filtrado como me indicaste, en la sentencia SQL en DtsDetalle. pero:
- Yo estoy haciendo la relación maestro/detalle al nivel de los ClientDataSet y no de los IBDataSet, entonces ¿Porqué debo colocar el parámetro allí, si en Delphi 5 funcionaba como lo describi en mi mensaje inicial?
- El error inicial ya no aparece, pero ahora me muestra otro: 'Key violation', sin más texto. Por ahora no he podido realizar muchas pruebas para establecer si el nuevo inconveniente concierne a la parametrización de la relación maestro/detalle, pero todo parece indicar que sí. ¿Hay otras cosas a tener en cuenta al elaborar el tipo de relación que requiero, en Delphi 2007?
- ¿Donde podría encontrar ayuda acerca del IBExpress 11 y sus componentes?

Muchas gracias por tu ayuda...

Al González 06-07-2008 08:23:49

Cita:

Empezado por GuerreroDelphi (Mensaje 298510)
Gracias, Al Fernández...

¡Ah! Tú eres el que me cambia totalmente el apellido, ya sólo falta que me llames Chente. :D

Cita:

Empezado por GuerreroDelphi (Mensaje 298510)
...Añadí en parametro del filtrado como me indicaste, en la sentencia SQL en DtsDetalle. pero:
- Yo estoy haciendo la relación maestro/detalle al nivel de los ClientDataSet y no de los IBDataSet, entonces ¿Porqué debo colocar el parámetro allí, si en Delphi 5 funcionaba como lo describi en mi mensaje inicial?...

Es posible que algunas cosas hayan cambiado en el componente TClientDataSet después de Delphi 5. El parámetro en el conjunto de datos proveído hace que la carga de filas en el conjunto de datos cliente sea muy eficiente, ya que sólo extraerá de la base de datos los registros detalle que correspondan a los registros maestros donde te posiciones. Si de 100 registros maestros sólo navegas dentro de los primeros cinco, sólo se cargarán en memoria los detalles de esos cinco y no de todos los 100 registros maestros. Quizá en Delphi 5 esta característica no estaba presente aún y lo normal era cargar todos los registros detalle a un tiempo. Eso explicaría por qué te funcionaba sin el parámetro (aunque me gustaría poder echarle una mirada al .pas de la clase TClientDataSet de Delphi 5 para estar seguro).

Cita:

Empezado por GuerreroDelphi (Mensaje 298510)
...El error inicial ya no aparece, pero ahora me muestra otro: 'Key violation', sin más texto...

Bajo circunstancias como las actuales, ese otro error suele aparecer cuando tienes algún campo marcado con la bandera pfInKey (en su propiedad ProviderFlags) y, por la forma en que están relacionados los conjuntos de datos, resulta que una misma fila detalle se repite para dos o más registros maestros. ¿Tal condición ocurre? En su caso, una solución es desactivar la bandera pfInKey, pero entonces el conjunto de datos detalle ya no sabrá cuál es el campo llave (inconveniente en caso de que estés usando el UpdateMode upWhereKeyOnly, que para mi gusto es el mejor).

Esperamos tus avances.

Al González. :)

GuerreroDelphi 10-07-2008 19:25:20

Delphi 2007 - Maestro detalle TIBDataSet+TDataSetProvider+TClientDataSet
 
Hola, Al:
Primero que todo, discúlpame por la confusión en tu apellido (me confundí por la zeta,:D).

Bueno, al fin logré establecer la relación maestro detalle gracias a tus indicaciones, pero demoré buen tiempo en detectar que ya estaba solucionado, porque, después de abrir los ClientDataSets maestro y detalle, el detalle no muestra los registros correspondientes, hasta que no empiezo a navegar en el maestro, lo cual solucioné, invocando el método First del ClientDataSet maestro. ¿Hay forma de que, al abrirlos, automáticamente me refresque el detalle?, porque sucede que tengo una aplicación bastante grande y temo que algo quede mal sin darme cuenta.

En cuanto al inconveniente del 'Key violation', el problema lo corregí incluyendo el campo llave en la sentencia del detalle; lo que tampoco entiendo, pues no existían registros con la exactamente misma información.

De todas formas, estoy trabajando bien en la forma que te cuento, pero me gustaría optimizar, si es posible.

¿Sabes dónde puedo encontrar información mucho mas detallada sobre el manejo de TClienDataSet?, pues lo que consigo casi siempre son descripciones de cada propiedad o evento, pero desearia algo más de contexto...

Muchas gracias por tu ayuda, Chente.

Saludos,
GuerreroDelphi


Al González 11-07-2008 22:00:10

¡Hola!

Cita:

Empezado por GuerreroDelphi (Mensaje 299370)
...al fin logré establecer la relación maestro detalle gracias a tus indicaciones, pero demoré buen tiempo en detectar que ya estaba solucionado, porque, después de abrir los ClientDataSets maestro y detalle, el detalle no muestra los registros correspondientes, hasta que no empiezo a navegar en el maestro, lo cual solucioné, invocando el método First del ClientDataSet maestro. ¿Hay forma de que, al abrirlos, automáticamente me refresque el detalle?...

Que bueno que te ayudó mi consejo. Es extraño ese comportamiento. Cuando abres un conjunto de datos, éste se posiciona en su primera fila, y cada vez que un conjunto de datos se posiciona en una fila, sus subordinados conjuntos de datos detalles responden en consecuencia. No me explico qué pueda estar causando tal anomalía, pero a mí no me ha pasado (Delphi 7).

Un favor: ¿podrías elaborar una "prueba aislada" que puedas enviar a mi correo o anexar como .zip en este mismo hilo (en caso de que aún en esa prueba aislada siga presentándose el problema) para compilarla y analizarla con detenimiento en mi Delphi 2007? Una pequeña aplicación con dos TClientDataSet maestro-detalle y demás componentes necesarios ya armada. Me gustaría ver el trazo que sigue dentro de la VCL para descubrir por qué no te carga los detalles desde la apertura. :)


Cita:

Empezado por GuerreroDelphi (Mensaje 299370)
...En cuanto al inconveniente del 'Key violation', el problema lo corregí incluyendo el campo llave en la sentencia del detalle; lo que tampoco entiendo, pues no existían registros con la exactamente misma información...

De cualquier forma es muy buena práctica incluir el campo llave de los registros en los conjuntos de datos.


Cita:

Empezado por GuerreroDelphi (Mensaje 299370)
...¿Sabes dónde puedo encontrar información mucho mas detallada sobre el manejo de TClientDataSet?, pues lo que consigo casi siempre son descripciones de cada propiedad o evento, pero desearia algo más de contexto...

Fuentes que recomiendo:
1. Código fuente de la VCL (es muy enriquecedor atreverse a bucear en él).
2. Estupendos foros como este.
3. Libros de autores reconocidos como Ian Marteens, Marco Cantú, entre otros.
4. Bitácoras sobre Delphi y sus autores.
5. Cursos Delphi, como este que encontré de Ian Marteens: http://www.marteens.com/cdb1ad.pdf, o el que ofrezco en Sistemas GH.

Un abrazo maestro.

Al González. :)


La franja horaria es GMT +2. Ahora son las 09:00:40.

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