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 14-11-2003
mgaray mgaray is offline
Miembro
 
Registrado: nov 2003
Posts: 32
Poder: 0
mgaray Va por buen camino
Insercion maestro/detalle para aplicacion cliente servidor

Hola a todos:
Tengo problemas con la insercion en tablas maestro detalle ya que como tiene que ser una aplicacion cliente servidor cuando dos usuarios entran, YO genero un mismo numero para ambos pero al momento de guardar a un lo deja GUARDAR y al otro le marca un error por clave duplicada, cabe enfatizar que el numero lo genero YO , dicho numero es un consecutivo, que me recomiendan? . La otra es que quiero guardar su detalle al momento de haber guardado el maestro y si hay problemas entonces no guardar. Espero me puedan ayudar, de antemano muchas gracias.

Última edición por mgaray fecha: 14-11-2003 a las 16:22:34.
Responder Con Cita
  #2  
Antiguo 14-11-2003
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
En primer lugar te recomiendo que abras dos hilos distintos para dos preguntas distintas, tal como se recomienda en la guia de estilo.

La solucion natural para evitar el problema de duplicidad de clave es el uso de generadores, secuencias o como lo llame tu base de datos, que es un mecanismo independiente de la transaccion que te asegura un numero diferente para cada registro. Lamentablemente no te puedo orientar mas ya que no indicas en que base de datos trabajas.

Para tu problema de guardar todo o nada (tecnicamente una operacion atomica) la mejor solucion es valerse de una transaccion, y si algo falla en el transcurso de la actualizacion, hacer un rollback, de lo contrario un commit, y listo.

Hasta luego.


__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate

Última edición por jachguate fecha: 14-11-2003 a las 16:46:55.
Responder Con Cita
  #3  
Antiguo 14-11-2003
mgaray mgaray is offline
Miembro
 
Registrado: nov 2003
Posts: 32
Poder: 0
mgaray Va por buen camino
Antes que nada perdon por no respetar las recomendaciones de estilo del foro, pero es que tengo muchos problemas para enviar mis hilos ya que no se porque razon el acceso me es denegado frecuentemente, de cualquier manera te agradezco el comentario.
Pasando a otro asunto, estoy trabajando con sql server 2000, con la generación de un campo autonumerico se resuelve el problema de los usuarios. Tu que dices?. Pero aunado a esto esta mi preocupación de como hacer para que el numero que se asigne en la maestro se lo lleve la tabla detalle, ya que si manejo el caso de un campo autonumerico no sabre que numero le asigno el sql server hasta que se halla guardado y para eso tendria que refrescar la consulta y despues dar de alta los detalles, que me sugieres?.
Gracias por tu ayuda.
Responder Con Cita
  #4  
Antiguo 15-11-2003
Lmas Lmas is offline
Miembro
 
Registrado: jul 2003
Ubicación: España
Posts: 27
Poder: 0
Lmas Va por buen camino
Hola mgaray.

Sin duda alguna, la mejor forma de resolver el problema que planteas de los usuarios es el uso de campos autonuméricos; y en cuanto a los problemas de inserciones y modificaciones en relaciones maestro-detalle...

Uns estructura típica de relación maestro-detalle con una tabla de Facturas y otra de FacturasDetalle:
Código:
Facturas
(
  id  -  Autonumérico
  ClienteId - Entero largo (Cliente de quien es la factura)
   ...
   resto de campos
);

FacturasDetalle
(
  id - Autonumérico
  FacturaId - Entero largo (A qué factura de la tabla anterior pertenece este detalle)
  ...
  resto de campos
);
y para mostrar estas tablas tienes dos vistas (o consultas en Access) vwFacturas y vwFacturasDetalle en las que muestras el nombre del cliente, en vez de ClienteId en la primera, y haces algo parecido con la segunda.

En Delphi tendrás dos TADODataset o similar, dsFacturas cuyo origen de datos sea vwFacturas y, dsFacturasDetalle cuyo origen sea vwFacturasDetalle.

Entonces, debes configurar las siguientes propiedades de los Recordset para que al hacer las inserciones en la tabla maestra, automáticamente ADO actualice el campo incremental del registro recién insertado (sólo el nuevo registro, y no toda la tabla), para así poder añadir registros detalle.

En el evento BeforePost de dsFacturas (yo lo pongo en este evento, aunque si no hacer posteriores Requerys o cosas similares, supongo que podría ponerse en el AfterOpen)

Código:
  dsFacturas.Properties['Unique Table'].Value := 'Facturas';
  dsFacturas.Properties['Update Criteria'].Value := adCriteriaUpdCols;
  dsFacturas.Properties['Update Resync'].Value := adResyncAll;
  dsFacturas.Properties['Resync Command'].Value := 'SELECT * FROM vwFacturas WHERE vwFacturas.id = ?';

  y para los detalle:


  dsFacturasDetalle.Properties['Unique Table'].Value := 'FacturasDetalle';
  dsFacturasDetalle.Properties['Update Criteria'].Value := adCriteriaUpdCols;
  dsFacturasDetalle.Properties['Update Resync'].Value := adResyncAll;
  dsFacturasDetalle.Properties['Resync Command'].Value := 'SELECT * FROM vwFacturasDetalle WHERE vwFacturasDetalle.id = ?';
Unique Table, indica que sólo se actualice esa tabla de las que forman la vista y ADO no intente actualizar las tablas relacionadas.
Update Criteria, indica el criterio de comparación de las columnas en la actualización (la clave primeria, timestamp, etc... Los posibles valores están en ADOInt.pas)
Update Resync, indica cuando sincronizar la tabla. Los posibles valores también están en ADOInt.
Resync Command, es la instrucción SQL que ADO ejecutará para sincronizar la tabla. En ella ADO sustituye el "?" por la clave primaria de la tabla; en este caso, el campo autoincremental.

Para hacerlo como te indica jachguate en un todo o nada mediante transacciones:
Código:
  Conexion.BeginTrans;
  try
    dsFacturas.Append;
    tbFacturasClienteId.AsInteger := XXXX;
    dsFacturas.Post;
    // Primer detalle
    dsFacturasDetalle.Append;
    tbFacturasDetalleFacturaId.AsInteger := tbFacturasId.AsInteger;
    dsFacturasDetalle.Post;
    // Segundo detalle
    dsFacturasDetalle.Append;
    tbFacturasDetalleFacturaId.AsInteger := tbFacturasId.AsInteger;
    dsFacturasDetalle.Post;
    Conexion.CommitTrans;
  except
    Conexion.RollbackTrans;
  end;
La propiedad LockType de los Datasets debe ser ltOptimistic.

El quid de la cuestión es que ADO automáticamente, tras "dsFacturas.Post", lanza un "SELECT @@identity" que devuelve el valor del último campo incremental que se haya generado en la conexión y tras ese comando lanza el que se haya puesto en la propiedad "Resync Command" del Recordset, sustituyendo el "?" por el valor que acaba de obtener de la consulta anterior. De esta forma en "tbFacturasDetalleFacturaId.AsInteger := tbFacturasId.AsInteger" se está dando al registro detalle la clave primaria con la que está relacionada. Todo este proceso se puede ver con el SQL Profiler del SQL Server.

Lo anterior funciona a partir de SQL Server 2000 y de Access 2000, en versiones anteriores no (no recuerdo exactamente si era necesario también el MDAC 2.5 o superior, lo puedes consultar el el MSDN de Microsoft).

Bueno, vale ya de tanto rollo.

SalU2
__________________
Una cosa es una cosa, y otra cosa es otra cosa...

Última edición por Lmas fecha: 15-11-2003 a las 14:05:50.
Responder Con Cita
  #5  
Antiguo 17-11-2003
SANTIAGUERO SANTIAGUERO is offline
Registrado
 
Registrado: nov 2003
Ubicación: Republica Dominicana
Posts: 3
Poder: 0
SANTIAGUERO Va por buen camino
Quizas esto te de algo de luz, en SQL existe una fucion o veriable que te devuelve el ultimo numero autogenerado en @@identity

Espeo haber cooperado contigo
Responder Con Cita
  #6  
Antiguo 17-11-2003
mgaray mgaray is offline
Miembro
 
Registrado: nov 2003
Posts: 32
Poder: 0
mgaray Va por buen camino
Hola:
Solo para agradecerles su atención y amabilidad al responderme sobre mis problemas, hice lo que me sugirieron y todo resulto a la perfección, muchas gracias por su ayuda.

Saludos

Mgaray.
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 19:31:39.


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