Sie sind auf Seite 1von 7

Guas tcnicas Grupo Danysoft:

Aplicaciones de Bases de Datos con Delphi - II

Equipo Grupo Danysoft junio de 2003 - (902) 123146 www.danysoft.com

Guas Tcnicas Grupo Danysoft: Aplicaciones de Bases de datos con Delphi

Este documento se ha realizado utilizando Doc-To-Help , distribuido por :

Danysoft Internacional Avda de Espaa 17 28100 Alcobendas Madrid Tfno. 902.123146 Fax. 902.123145 http://www.danysoft.com http://www.danyshop.com danysoft@danysoft.com

www.danysoft.com - Pgina 2/7

Guas Tcnicas Grupo Danysoft: Aplicaciones de Bases de Datos con Delphi

Aplicaciones de bases de datos con Delphi


Una estrategia para su desarrollo (2da. entrega) En la primera entrega vimos como los componentes ClientDataSet y DataSetProvider nos permiten separar la lgica de datos de la lgica de acceso a datos. Tambin vimos cmo algunas caractersticas de estos componentes hacen ms fcil la resolucin de actualizaciones incluso en escenarios complejos como el de las relaciones maestro/detalle. En todos los casos no slo no tenemos que preocuparnos por la generacin de las sentencias SQL de INSERT, DELETE y UPDATE ya que el componente DataSetProvider se encarga de generarlas por nosotros. Tampoco tenemos que preocuparnos por el orden en el que debemos resolver las actualizaciones sobre todo en el caso de relaciones maestro/detalle ya que el DataSetProvider sabe muy bien cmo hacer su trabajo. Cuando resolvemos las actualizaciones a dos tablas que mantienen una relacin maestro/detalle entre s, el orden en el que las resolvemos depende del tipo de actualizacin. Por ejemplo, si estamos insertando una orden, entonces debemos actualizar primero la tabla maestro (Orders) y luego la tabla detalle (Items). Si por el contrario estamos eliminando una orden, debemos eliminar primero l o los registros del detalle (Items) y luego el registro del maestro (Orders). El proceso de resolucin de actualizaciones La resolucin de actualizaciones es tarea del componente DataSetProvider. Podemos personalizar este proceso ya sea modificando aspectos generales por medio de propiedades o escribiendo nuestro propio proceso de resolucin de actualizaciones. UpdateMode La propiedad UpdateMode del DataSetProvider nos permite controlar la generacin de las sentencias SQL de DELETE y UPDATE.

Cuando eliminamos o modificamos un registro debemos proveer informacin suficiente para localizar el registro en cuestin. Esto lo hacemos por medio de la clusula WHERE. Esta propiedad controla precisamente qu campos deben ser incluidos en la clusula WHERE generada. El valor upWhereAll incluye todos los

www.danysoft.com - Pgina 3/7

Guas Tcnicas Grupo Danysoft: Aplicaciones de Bases de datos con Delphi

campos. El valor upWhereChanged incluye slo los campos modificados y los campos que forman la clave primaria. El valor upWhereKeyOnly incluye slo los campos que forman la clave primaria. Los campos incluidos en la clusula WHERE tienen impacto sobre el control de concurrencia y el rendimiento. En un entorno de varios usuarios concurrentes es posible que dos usuarios modifiquen el mismo registro al mismo tiempo. Para comprender bien este problema debemos tener bien claro el proceso completo. Un usuario abre un formulario ante lo que nuestra aplicacin obtiene datos de la base de datos. Como el ClientDataSet mantiene los cambios en memoria es posible que otro usuario obtenga los mismos datos, los modifique y aplique las modificaciones antes que el primer usuario lo haga. Aqu es donde debemos controlar la concurrencia. Al incluir todos los campos en la clusula WHERE, el DataSetProvider utiliza los valores originales para localizar el registro en cuestin. Esto significa que si otro usuario ha modificado el registro luego de que el primer usuario los haya obtenido y antes de que haya aplicado los cambios, el registro no ser localizado y la actualizacin del primer usuario fallar. Esto es vlido para todos los campos salvo para los campos BLOB. En este caso no tenemos forma de detectar si otro usuario ha modificado el mismo registro. Dependiendo del nivel de control de concurrencia que necesitemos implementar podemos utilizar el valor upWhereAll (alto), upWhereChanged (medio) o upWhereKeyOnly (bajo). Si la tabla que estamos actualizando tiene muchos campos est claro que el valor upWhereKeyOnly tendr mejor rendimiento que upWhereAll. No es lo mismo hacer una comparacin que cincuenta. ProviderFlags Para resolver ambos problemas a la vez, es decir, implementar un alto control de concurrencia y obtener el mejor rendimiento posible al mismo tiempo, lo ms comn es crear un campo que acte como bandera y nos permita determinar si el registro ha sido modificado con slo evaluar su valor. Cada vez que insertamos, eliminamos o modificamos un registro, le asignamos un valor nuevo a este campo. Luego, slo deberamos incluir en la clusula WHERE este campo y los campos que forman la clave primaria.

Para ello debemos utilizar la propiedad ProviderFlags de cada uno de los campos del DataSet utilizado por el DataSetProvider para obtener datos. La propiedad ProviderFlags es un conjunto de valores de los cuales en este caso nos interesa slo pfInWhere. El valor True le indica al DataSetProvider que el campo debe ser incluido en la clusula WHERE. El valor False indica que no lo debe incluir.

www.danysoft.com - Pgina 4/7

Guas Tcnicas Grupo Danysoft: Aplicaciones de Bases de Datos con Delphi

Eventos El componente DataSetProvider genera una serie de eventos que nos permiten personalizar el proceso de actualizacin. El siguiente grfico muestra la secuencia de eventos que genera el DataSetProvider:

El evento BeforeApplyUpdates se genera antes de comenzar el proceso de actualizacin. Es importante tener en cuenta que el proceso de actualizacin puede implicar la actualizacin de varios registros y varias tablas. Podemos escribir cdigo en este evento para realizar tareas previas al inicio del proceso de actualizacin como por ejemplo asignarle un nuevo valor al campo utilizado como bandera para verificar si un registro ha sido modificado por otro usuario. El evento BeforeUpdateRecord se genera antes de actualizar cada registro. En relaciones maestro/detalle este evento se genera para cada registro del maestro y para cada registro del detalle. En este evento podemos personalizar totalmente el proceso de actualizacin e informarle al DataSetProvider por medio del parmetro Applied que nos hemos encargado del registro y que no debe resolver su actualizacin. El evento AfterUpdateRecord se genera despus de actualizar cada registro. En este evento podemos realizar tareas complementarias como actualizar otras tablas. Por ejemplo, podramos actualizar el campo OnOrder de la tabla productos (Parts) para cada tem (Items) de una orden (Orders). En este evento no tenemos que preocuparnos por controlar transacciones ya que el DataSetProvider se encarga de hacerlo por nosotros. Incluso podemos llamar al mtodo ApplyUpdates de otros ClientDataSet que el DataSetProvider seguir teniendo cuidado de controlar las transacciones. Veamos en detalle como sera la secuencia. En el caso de una nueva orden, se inicia una transaccin al insertar el registro maestro. Los registro del detalle son insertado en el contexto de la misma transaccin del registro maestro y si actualizamos otras tablas en este evento todo se har en el contexto de la misma transaccin. Si ocurre un error al actualizar alguna de las tablas se generar una excepcin y la transaccin ser finalizada cancelando todos los cambios realizados.

www.danysoft.com - Pgina 5/7

Guas Tcnicas Grupo Danysoft: Aplicaciones de Bases de datos con Delphi

Consultas complejas Otro problema que podemos resolver con facilidad en el componente ClientDataSet es la utilizacin de consultas complejas o la actualizacin de vistas de slo lectura. La siguiente sentencia SQL podra resultar en un conjunto de slo lectura:
SELECT Items.OrderNo, Items.ItemNo, Items.PartNo, Parts.Description, Parts.ListPrice, Items.Qty, Items.Discount FROM Items INNER JOIN Parts ON (Items.PartNo = Parts.PartNo) WHERE Items.OrderNo = :OrderNo

Con los componentes ClientDataSet y DataSetProvider, no. Es ms, en el ClientDataSet podremos asignarles valores a los campos Description y ListPrice sin ninguna dificultad simplificando la creacin de una interface de usuario amigable. Sin embargo, para que el DataSetProvider pueda resolver las actualizaciones a este conjunto de datos debemos hacer algo ms. La propiedad ProviderFlags de los campos tambin nos permiten resolver situaciones como ests. En este caso no queremos que la sentencia SQL generada automticamente por el DataSetProvider contenga los campos Description y ListPrice ya que estos campos no forman parte de la tabla Items. Lo que debemos hacer entonces es asignarle a la propiedad ProvierFlags.pfInUpdate el valor False. Esto le indica al DataSetProvider que estos campos no deben ser incluidos en las sentencias SQL de INSERT y UPDATE. Claro que tambin debemos asignarle el valor False a la propiedad ProviderFlags.pfInWhere ya que tampoco deben ser incluidos en la clusula WHERE. OnGetTableName En ocasiones el componente DataSetProvider no puede determinar el nombre de la tabla que debe actualizar. Para estas situaciones genera el evento OnGetTableName en el cual debemos proveer el nombre de la tabla que debe ser actualizada en el parmetro TableName. En una sentencia SQL como la anterior los componentes de acceso a datos basados en BDE y en ADO pueden determinar el nombre de la tabla que debe ser actualizada. Sin embargo, los componentes de acceso a datos basados en InterBase Express no pueden. En cualquier caso, si el DataSetProvider no puede determinar el nombre de la tabla que debe actualizar y no proveemos un manejador para el evento OnGetTableName, genera un mensaje de error indicando que no puede determinar el nombre de la tabla que debe actualizar. Campos persistentes El uso de campos persistentes nos ofrece la ventaja de trabajar con los objetos TField de manera visual en tiempo de diseo. Podemos asignarles valores a sus propiedades y manejadores de eventos para sus eventos. Sin embargo hay ocasiones en las cuales no podremos utilizar campos persistentes debido a que el tipo de objeto descendiente de la clase TField puede variar de una base de datos a otra o de una tecnologa de acceso a datos a otra. Por ejemplo, utilizando el BDE para acceder a tablas Paradox

www.danysoft.com - Pgina 6/7

Guas Tcnicas Grupo Danysoft: Aplicaciones de Bases de Datos con Delphi

obtendremos un objeto de tipo TStringField para el campo Description de la sentencia SQL anterior. Utilizando ADO para acceder a tablas MSAccess obtendremos un objeto de tipo TWideStringField para el mismo campo. Si en el ClientDataSet hemos creado campos persistentes entonces no ser posible cambiar de una base de datos a otra y de una tecnologa de acceso a datos a otra con mucha facilidad. La nica solucin es no crear campos persistentes y asignar valores a las propiedades y manejadores de eventos a los eventos de los campos por cdigo en tiempo de ejecucin. Es mucho ms incmodo trabajar de esta forma pero es la nica solucin que nos dar libertad para elegir la base de datos y la tecnologa de acceso a datos utilizada. En lo que respecta a las propiedades de los campos, podemos crear campos persistentes en los DataSet utilizados por el DataSetProvider para obtener los datos e indicarle al DataSetProvider que queremos que propague estos valores al ClientDataSet. De esta forma podramos resolver parte del problema y slo nos restara asignar manejadores de eventos por cdigo. La propiedad Options.poIncFieldProps del DataSetProvider nos permite controlar este comportamiento. Conclusiones Hemos visto las caractersticas del componente DataSetProvider para el manejo del proceso de actualizacin. Nos ofrece la ventaja de generar automticamente las sentencias SQL de actualizacin y ejecutarlas en el orden correcto. Tambin nos permite personalizar el proceso de actualizacin modificndolo en todo o en parte. Adems, las sentencias SELECT complejas o las vistas de slo lectura no son un problema para el DataSetProvider. En la prxima entrega veremos cmo gestionar la resolucin de errores de actualizacin. Ms informacin En el curso de tecnicas avanzadas de programacin Delphi, del cual puede ver ms informacin y contenidos en www.danyform.com o contactando con formacin@danysoft.com

www.danysoft.com - Pgina 7/7

Das könnte Ihnen auch gefallen