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 31-03-2005
Yoli Yoli is offline
Miembro
 
Registrado: dic 2004
Posts: 36
Poder: 0
Yoli Va por buen camino
problema con mastersource

Hola a todos, estoy desarrollando un formulario maestro/detalle, con delphi 6, firebird 1.5 e IBX. Para esto tengo 2 TIBtable.

en el TIBtable1 esta la tabla maestro (la clave principal es ID_COTIZACION) y en el TIBtable2 esta la tabla detalle (la clave foranea es ID_COTIZACION1), y en esta tengo como mastersource a dsMaestro (datasource), y en el field link desingner le dije: ID_COTIZACION1 - ID_COTIZACION. Ahora bien, el problema que tengo es que al momento de guardar, se guardan todos los campos en la tabla maestro y todos los campos de detalle excepto el campo ID_COTIZACION1, es decir, no guarda automaticamente en la tabla detalle el campo que relaciona al maestro con el detalle, es como si no funcionara el mastersource. el codigo que tengo en el boton guardar es:

dsCotizacion.DataSet.Post;
dsCotizacion.DataSet.Refresh;

bueno espero puedan ayudarme con este problema. Saludos y gracias de antemano.
Responder Con Cita
  #2  
Antiguo 31-03-2005
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 28
jachguate Va por buen camino
Estrictamente no es que el master/detail no funcione, simpelemente que delphi no asigna el valor de los campos que la relacionan con el padre a la tabla hija.

Vos lo podes solucionar fácilmente en el evento OnNewRecord de la tabla hija:

Código Delphi [-]
Procedure Forma1.TablaHijaNewRecord(DataSet : TDataSet);
Begin
  TablaHijaNumeroFactura.AsInteger := TablaPadreNumeroFactura.AsInteger;
end;

Suponiendo en este caso, que el campo NumeroFactura es el que relaciona ambas tablas.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #3  
Antiguo 01-04-2005
Yoli Yoli is offline
Miembro
 
Registrado: dic 2004
Posts: 36
Poder: 0
Yoli Va por buen camino
Gracias por responder jachguate, hice lo que me dijistes:

Vos lo podes solucionar fácilmente en el evento OnNewRecord de la tabla hija:

Código Delphi [-]
 Procedure Forma1.TablaHijaNewRecord(DataSet : TDataSet);
 Begin
   TablaHijaNumeroFactura.AsInteger := TablaPadreNumeroFactura.AsInteger;
 end;

Suponiendo en este caso, que el campo NumeroFactura es el que relaciona ambas tablas.

Y me quedo asi.

procedure TdmTablas.IBTCotizacionDNewRecord(DataSet: TDataSet);
begin IBTCotizacionDID_COTIZACION1.AsInteger:=IBTCotizacionID_COTIZACION.AsInteger;
end;

pero ahora me lanza otro error que dice:

'violation of FOREING KEY constratint "FK_ID_COTIZACION1" on table "COTIZACIOND"

Esto me pasa a la hora de insertar el 2do. registro en el grid, es decir, cuando ingreso el primer registro en el grid todo bien, pero en el momento que presiono la flecha hacia abajo para que aparezca la otra linea en el grid , me lanza este error. no se que estoy haciedo mal, espero puedas ayudarme con estoy. Saludos y gracias de nuevo.
Responder Con Cita
  #4  
Antiguo 01-04-2005
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 28
jachguate Va por buen camino
Ahora ocurre que estas intentando insertar el detalle en la base de datos sin haber insertado primero el padre. Hay varias formas de enfrentarlo... lo que me parece mas adecuado dado tu planteamiento es hacer algo como esto en el evento BeforePost de la tabla hija:

Código Delphi [-]
Procedure TablaHijaBeforePost(parametros... );

Begin
  if TablaPadre.State = dsInsert Then
    TablaPadre.Post;
end;
Lo que forzará a que el registro padre se inserte primero a la base de datos.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #5  
Antiguo 01-04-2005
Yoli Yoli is offline
Miembro
 
Registrado: dic 2004
Posts: 36
Poder: 0
Yoli Va por buen camino
[quote=jachguate]Ahora ocurre que estas intentando insertar el detalle en la base de datos sin haber insertado primero el padre. Hay varias formas de enfrentarlo... lo que me parece mas adecuado dado tu planteamiento es hacer algo como esto en el evento BeforePost de la tabla hija:

Código Delphi [-]
 Procedure TablaHijaBeforePost(parametros... );
 
 Begin
   if TablaPadre.State = dsInsert Then
     TablaPadre.Post;
 end;
Lo que forzará a que el registro padre se inserte primero a la base de datos.

Gracias por tu respuesta, lo voy hacer, pero antes de hacer te pregunto. Si inserto del maestro(padre) en la base de datos antes de insertar los registro de detalle (hijo) y deseo cancelar en algun momento, significa que tengo que eliminar el registro padre que inserte. Esta es la mejor forma de hacerlo?. lo que intento hacer es insetar todo de una vez, de manera que si deseo cancelar en algun momento, no tengo que eiliminar nada de la base de datos. segun tú, ¿ cual es la mejor forma de insertar registros en un formulario maestro/detalle? . Saludos
Responder Con Cita
  #6  
Antiguo 01-04-2005
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 28
jachguate Va por buen camino
Pues eso nuevamente hay varias formas de enfrentarlo.

La primera y mas simple, es encerrar todo en una transacción (no poner las transacciones automáticas), y si después se quiere cancelar bastará con hacer Transaccion.RollBack. Es una solución mas simple pero puede ocasionarte conflictos con locks en la base de datos, principalmente si el usuario A decide ir a almorzar habiendo dejado abierta la transacción, cosa poco recomendable.

Otra, un poco mas compleja pero mas funcional, es mantener todas las actualizaciones en cache y voltearlas luego todas juntas a la base de datos, sobre lo cual te recomiendo buscar y leer alguna información. Comenzá por la ayuda de la propiedad CachedUpdates.

Espero haberte ayudado con esta pequeña explicación.

Hasta luego

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #7  
Antiguo 01-04-2005
Yoli Yoli is offline
Miembro
 
Registrado: dic 2004
Posts: 36
Poder: 0
Yoli Va por buen camino
Espero no molestarte con tantas preguntas y de nuevo gracias por contestarlas. Ya gice el codigo del beforepost, y ahora me sale un error que dice: stackoverflow y aparce aparece al momento de presionar la flecha abajo el en grid despues de haber insertado el primer registro en el grid. Sabes a que se debe esto? . gracias. saludos
Responder Con Cita
  #8  
Antiguo 01-04-2005
Yoli Yoli is offline
Miembro
 
Registrado: dic 2004
Posts: 36
Poder: 0
Yoli Va por buen camino
Espero no molestarte con tantas preguntas y de nuevo gracias por contestarlas. Ya hice el codigo del beforepost, y ahora me sale un error que dice: stackoverflow y aparce aparece al momento de presionar la flecha abajo el en grid despues de haber insertado el primer registro en el grid. Sabes a que se debe esto? . gracias. saludos
Responder Con Cita
  #9  
Antiguo 01-04-2005
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 28
jachguate Va por buen camino
El stack overflow ocurre regularmente con una mala llamada recursiva que llena la pila, puesto que no termina nunca la recursión.

Aqui seguramente hay una llamada recursiva indirecta. No puedo probarlo ahora con las ibx, pero estoy casi seguro que se trata de un problema originado en el código que tu tengas asociado a los eventos de la tabla padre (quizas también en el beforepost de la tabla padre).

Lo que te recomiendo es poner un breakpoint en el evento BeforePost de la tabla hija, y una vez llegada la ejecución a ese punto, continuar con la ejecución paso a paso, de manera que vos mismo(a) encontres donde se origina la recursión.

¿una solución?.. quizas una variable booleana sea suficiente (normalmente llamada bandera)... pero eso dependerá de lo que encontres en tu búsqueda.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #10  
Antiguo 01-04-2005
Yoli Yoli is offline
Miembro
 
Registrado: dic 2004
Posts: 36
Poder: 0
Yoli Va por buen camino
Ya estoy buscando informacion sobre el cachedupdates. Gracias por orientarme con respcto a este tema. Ahhh y ya soluciones lo del satck overflow. Volvi a colocar un codigo que habia borrado en el evento OnEnter del grid:

if (DSCotizacion.DataSet.State = dsEdit) or (DSCotizacion.DataSet.State = dsInsert) then
begin
DSCotizacion.DataSet.Post;
DSCotizacion.DataSet.Refresh;
end;

De nuevo gracias por tu respuestas y recomendaciones, me fuiste de gran ayuda. Saludos.
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


La franja horaria es GMT +2. Ahora son las 18:05: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