Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Conexión con bases de datos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 11-11-2009
alquimista_gdl alquimista_gdl is offline
Miembro
 
Registrado: ago 2008
Ubicación: Guadalajara, México
Posts: 78
Poder: 17
alquimista_gdl Va por buen camino
Question edbclient: no corresponding master record found

Hola,

tengo una relación Maestro/detalle usando ClientDataSets anidados; todo funcionaba a la perfección... inserciones, borrados, cambios en padre, en hijo, y todo estaba bien. Ayer tuve que modificar la tabla padre, que realmente es un view... Comenzaron los problemas. Al insertar un hijo, ClientDataSet me envía el error "edbclient: no corresponding master record found".
He debuggeado, y el nuevo registro hijo contiene correctamente la FK al padre.
hice una forma de prueba, con dos grids... el del padre y el hijo, y al mover los registros de padre, hay sincronización correcta con el grid hijo.

Por si las dudas, al insertar el hijo, hice esto:

Cita:
procedure Tz_DataModule_Seguridad.ClientDataSet_Usuario_Grupo_xBeforePost(
DataSet: TDataSet);
begin
if DataSet.State = dsInsert then
begin

DataSet.FieldByName( 'usuario_id' ).AsString:= Self.ClientDataSet_Usuario.FieldByName( 'usuario_id' ).AsString;

end;
Más no es necesario, ya que al parecer internamente se asignan estos valores, al tener ClientDataSet anidados.

Para la actualización de datos del ClientDataSet anidado, tengo esto:

Cita:
procedure Tz_DataModule_Seguridad.DataSetProvider_UsuarioGetTableName(
Sender: TObject; DataSet: TDataSet; var TableName: WideString);
begin
if DataSet.Name = 'SQLDataSet_Usuario_Grupo_x' then
TableName:= 'Z_USUARIO_GRUPO_X'
else if DataSet.Name = 'SQLDataSet_Usuario' then
TableName:= 'Z_USUARIO';

end;
Lo cual venía funcionando perfectamente.

Qué podrá ser??
Responder Con Cita
  #2  
Antiguo 11-11-2009
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.609
Poder: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Cita:
Empezado por alquimista_gdl Ver Mensaje
todo funcionaba a la perfección...Ayer tuve que modificar la tabla padre, que realmente es un view... Comenzaron los problemas. Al insertar un hijo, ClientDataSet me envía el error "edbclient: no corresponding master record found"...
Hola Guillermo.

Un par de preguntas: ¿cuáles fueron las modificaciones que hiciste a la tabla maestra? ¿en qué momento te aparece el error, al hacer el Post o al hacer el ApplyUpdates?

Al parecer, por alguna razón, no es guardado el registro maestro antes de guardar el registro detalle.

Te sugiero compilar la aplicación con la opción use debug DCUs, y observar el camino mostrado por la pila de llamadas (Ctrl+Alt+S) tras aparecer el mensaje de error. Esa información puede proporcionar mayores indicios.

Saludos.

Al González.
Responder Con Cita
  #3  
Antiguo 12-11-2009
alquimista_gdl alquimista_gdl is offline
Miembro
 
Registrado: ago 2008
Ubicación: Guadalajara, México
Posts: 78
Poder: 17
alquimista_gdl Va por buen camino
Hola Al,

Gracias por tu respuesta.

Se trata de un componente grid de DevExpress, de las últimas versiones que muestra los datos de un query. Anteriormente el query base era un simple "select * from z_usuario" y todo bien. Ahora es:

Cita:
select
z_usuario.usuario_id,
z_usuario.zus_usuario,
z_usuario.zus_nombre,
zus_contrasena,
zus_telefono,
zus_email,
zus_localidad,
zus_notas,
zgr_nombre
from z_usuario_grupo_x_v right join z_usuario
on(z_usuario.usuario_id = z_usuario_grupo_x_v.usuario_id)
order by zus_nombre
En el SQLDataSet y ClientDataSet he especificado el campo llave (usuario_id) y los campos que debe actualizar (los que tienen prefijo "zus"). Se trata de una relación N_N entre Usuarios y sus Grupos, y la consulta raíz se hace sobre la tabla de intersección "z_usuario_grupo_x" sobre su vista "z_usuario_grupo_x_v".

Por otro lado, y para indicar a qué tabla se hacen los cambios, en el evento OnGetTableName del Provider, tengo:

Cita:
procedure Tz_DataModule_Seguridad.DataSetProvider_UsuarioGetTableName(
Sender: TObject; DataSet: TDataSet; var TableName: WideString);
begin
if DataSet.Name = 'SQLDataSet_Usuario' then
TableName:= 'Z_USUARIO';

end;
Como me cansé un poco de el DataSet anidado (aunque estaba funcionando perfectamente antes de este cambio), opté por separar los dataset Meastro y Detalle, cada uno con su Provider; los relacionoa pata" vía código, y ahora al oprimir el botón de "Cambiar", sale el error "Key violation"

El error lo está marcando en este contexto:

Cita:
procedure TLista_bd.CambiosExecute(Sender: TObject);
begin
DataSource.DataSet.Refresh; <--- Aquí marca el error
DataSource.DataSet.Edit;
forma.MuestraForma;
DataSource.DataSet.Refresh;
self.Action_ControlBotonesExecute(self);

end;
Este es el método activado para cambiar el registro elegido en el Grid, cuando el usuario oprime el botón "cambiar", en donde DataSource es:

DataSource:= z_DataModule_Seguridad.DataSource_Usuario;


Alguna idea?
Responder Con Cita
  #4  
Antiguo 12-11-2009
alquimista_gdl alquimista_gdl is offline
Miembro
 
Registrado: ago 2008
Ubicación: Guadalajara, México
Posts: 78
Poder: 17
alquimista_gdl Va por buen camino
Al,

Creo que ya resolví parte del problema; como se trata de una relación N:N y en los Provider Flags de los campos, definía como llave a "usuario_id", eso causaba conflicto por que aparecían valores duplicados de tal llave, en función de que un usuario puede tener varios grupos.

Ahora solo me falta resolver algunos detalles asignación de FK al crear un registro hijo de la tabla de intersección, más creo que es más llevadero.

Gracias Al
Responder Con Cita
  #5  
Antiguo 12-11-2009
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.609
Poder: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Cita:
Empezado por alquimista_gdl Ver Mensaje
opté por separar los dataset Meastro y Detalle, cada uno con su Provider; los relacionoa pata" vía código, y ahora al oprimir el botón de "Cambiar", sale el error "Key violation"
Me es familiar este error cuando se establecen dos TClientDataSet en relación maestro-detalle y dicha relación, en lugar de ser uno a muchos, es muchos a muchos. Tiene que ver con la bandera pfInkey establecida en la propiedad ProviderFlags del campo de llave primaria de la tabla detalle.

Sucede que cuando cambias de registro maestro, los actuales registros detalles no se eliminan de la memoria del conjunto de datos, sino que se esconden, para dar paso a los registros detalles correspondientes al registro maestro seleccionado. Este mecanismo evita que vuelva a consultarse la base de datos si el usuario regresa al anterior registro maestro, pues sus correspondientes registros detalles fueron cargados en memoria anteriormente.

El inconveniente de este mecanismo es que no se permite que existan en memoria dos registros con la misma llave primaria, lo cual es bastante razonable, considerando que lo habitual de las relaciones maestro-detalle es que sean de tipo uno a muchos. Cuando son de tipo muchos a muchos, ocurre que un mismo registro puede cargarse dos o más veces en la memoria del conjunto de datos detalle (una copia por cada registro maestro asociado en donde haya estado el conjunto de datos maestro). Pero para que esto funcione, se necesita que no haya campo alguno, en el conjunto de datos detalle, con la bandera pfInKey (solución no siempre conveniente), o bien, limpiar con el método EmptyDataSet la memoria del conjunto de datos detalle justo antes de que ocurra navegación en el registro maestro. La desventaja de esta segunda opción es que se estará haciendo una lectura a la base de datos (de registros detalles) cada vez que se mueva de fila el conjunto de datos maestro —aunque se trate de una fila donde haya estado antes—

Por otro lado, no respondiste a mis dos preguntas iniciales. Personalmente no acostumbro usar los conjuntos de datos anidados, pues por lo general me resulta más práctico establecer las relaciones maestro-detalle en el lado cliente (similar a como tú lo has hecho ahora), pero podría valer la pena seguir intentándolo como lo planteaste al principio, investigando un poco más y realizando puntuales pruebas al respecto.

Seguimos de cerca.

Al González.

P.D. No había visto tu último mensaje, donde mencionas lo del campo llave, y que esencialmente es lo que expliqué arriba.

Última edición por Al González fecha: 12-11-2009 a las 19:56:04.
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
Clientes: Record Not Found en Evento ClientesFilterRecord behert666 MS SQL Server 4 02-06-2008 20:49:59
applyupdates (record not found or changed by another user) Stell Conexión con bases de datos 4 13-05-2008 14:36:20
Record not Found juliobuitrago Firebird e Interbase 0 25-12-2007 23:00:32
Record not found or changed by another user felixgo Conexión con bases de datos 1 30-09-2005 14:07:40
Record not found or changed by another user. Luis Conexión con bases de datos 2 12-08-2005 20:50:45


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


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