FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#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. |
|
|
|