FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
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. |
#2
|
||||
|
||||
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. |
#3
|
|||
|
|||
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. |
#4
|
|||
|
|||
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 ); 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 = ?'; 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; 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. |
#5
|
|||
|
|||
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 |
#6
|
|||
|
|||
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. |
|
|
|