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

 
 
Herramientas Buscar en Tema Desplegado
  #4  
Antiguo 13-10-2010
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
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 PabloZZZ Ver Mensaje
La consulta es:

Master.sql = Select * from master where id=152
Detail.sql = Select * from detalle where idmaster = :id

O sea que la relacion es Master.id = detalle.idmaster
Todas mis tablas tienen un campo ID [...] los fk son ID+el nombre de la tabla, por ej, IDMASTER.
Lo que pasa, que el CDS (o el DSP?) ve que los 2 tienen el campo ID y los asocia en base a ese campo, pensando que es el campo FK.
Cita:
Empezado por JosepGA Ver Mensaje
Te lo digo por que a mi me paso y me volvia loco hasta que encontre que este era el problema. Tuve que cambiar los nombres de los campos y relacionarlos con el mismo nombre.
Hola Pablo, José.

Pablo: Yo utilizo un estilo de nombres similar para los campos llaves, pero eso puede ocasionar el problema que explicas al usar conjuntos de datos anidados.

El problema tiene que ver con el método TDataPacketWriter.AddFieldLinks de la unidad Provider, el cual se encarga de establecer la relación de campos maestro-detalle a nivel del "paquete" de datos. Pero el "culpable" en sí no es él, sino el método GetDetailLinkFields de la mayoría de los componentes de acceso a consultas SQL, como por ejemplo TCustomSQLDataSet:

Código Delphi [-]
procedure TCustomSQLDataSet.GetDetailLinkFields(MasterFields, DetailFields: TList);

  function AddFieldToList(const FieldName: string; DataSet: TDataSet;
    List: TList): Boolean;
  var
    Field: TField;
  begin
    Field := DataSet.FindField(FieldName);
    if Field <> nil then
      List.Add(Field);
    Result := Field <> nil;
  end;

var
  I: Integer;
begin
  MasterFields.Clear;
  DetailFields.Clear;
  if (DataSource <> nil) and (DataSource.DataSet <> nil) then
    for I := 0 to Params.Count - 1 do
      if AddFieldToList(Params[i].Name, DataSource.DataSet, MasterFields) then
        AddFieldToList(Params[i].Name, Self, DetailFields);
end;

(por cierto, ¿qué componentes estás usando del lado del proveedor?)

De una forma por demás simple, todos los componentes query nativos asumen que los parámetros de relación (campos maestros) llevan el mismo nombre que los campos detalles a los cuales se aplica el Where. Por ello ocurre la incorrecta asignación que reportas, la cual no puede ser solucionada como lo intentaste porque el campo ID detalle ya viene incorrectamente "marcado" desde el proveedor como campo de relación.

Este problema ha sido reportado al fabricante desde el año 2002, sin que éste haya proporcionado aún una solución nativa (puede que Borland y Embarcadero estén muy apegadas al redundante estilo Customer.IDCustomer y no estimen gran cosa al elegante Customer.ID ). No obstante, en su sitio Web puedes encontrar dos temas que hablan del mismo problema, y al final de los cuales se dejan entrever posibles soluciones:

https://forums.codegear.com/message.jspa?messageID=2593
http://qc.embarcadero.com/wc/qcmain.aspx?d=1488

La primera es añadir una columna con alias a la consulta maestra:

Código SQL [-]
Select ID, ID As IDMaster, {otros campos} From Master [...]

Esto ya lo probé y funciona perfectamente. Sólo recuerda quitar las banderas pfInUpdate y pfInWhere del nuevo objeto campo, y asignarle el mismo valor que le des al campo ID.

La segunda sería redefinir el método virtual GetDetailLinkFields (que para eso son los métodos virtuales), creando una clase derivada de la que estés utilizando. Es un poco más elaborada, pues habría qué pensar qué código escribir en el nuevo método para hacerlo funcionar como queremos (las ideas que se proponen en el segundo enlace no me agradan mucho que digamos).

Ambas soluciones te evitarán tener que renombrar los campos, a lo cual José se vio obligado desafortunadamente (a diferencia de lo que sería un framework, una biblioteca general no debe imponer estilos de nombres).

Diviso una tercera solución que sería llamar con ciertos parámetros al método AddOptParameter de la interfaz DSBase maestra, pero no lo he estudiado del todo.

Espero haber ayudado de alguna manera. No dejes de retroalimentar este hilo.

Al González.
Responder Con Cita
 



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
ClientDataSets y Firebird Walterdf Conexión con bases de datos 19 27-08-2010 20:41:31
Capturar errores - ClientDataSets rochi Providers 3 22-11-2008 00:05:17
ClientDataSets con parámetros, no funciona la consulta rochi Providers 3 10-10-2008 20:47:24
ClientDataSets- Personalizar errores rochi Conexión con bases de datos 0 03-05-2008 06:47:52
Clientdatasets anidados con ADO Johnny Q Conexión con bases de datos 4 03-11-2005 02:53:25


La franja horaria es GMT +2. Ahora son las 07:29:16.


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