Actualizaciones y arrastrados con condición dinámica en Velneo

En esta vitamina aprenderás a hacer actualizaciones y arrastrados con condición dinámica en Velneo.

1. Planteando el problema

Los triggers (o eventos de tabla) y las actualizaciones (o macro-triggers automáticos) son dos funcionalidades muy utilizadas en nuestras bases de datos ya que nos aportan gran potencia de forma sencilla para gestionar cambios tanto en el registro que está siendo creado, modificado o eliminado como en los registros de otras tablas maestras o plurales enlazadas o de registros de tablas a las que accedemos mediante código.

La facilidad para crear las actualizaciones de tablas lleva implícito un efecto secundario y es que son disparados de forma automática cuando se producen cambios en campos que intervienen en la actualización, algo que es muy agradecido pero que en algunos casos puede resultar un problema. Veamos algunos ejemplos:

[pl_alertbox type=»warning»]

Caso A

Tenemos una tabla con actualizaciones que acumula valores en tablas maestras, pero cuando el alta se produce a través de un proceso de importación, no queremos que se ejecuten dichas actualizaciones porque duplican los valores que ya han sido importados en las tablas maestras.[/pl_alertbox]

[pl_alertbox type=»warning»]

Caso B

Tenemos una tabla de movimientos de almacén donde en el trigger posterior al alta, modificación o baja, cada vez que cambia el campo cantidad o precio se fuerza el recálculo «en cascada» de todos los registros, desde el modificado hasta el último de ese artículo calculando la existencia y el valor del almacén en cada movimiento. Pero nos gustaría que cuando hacemos cambios globales a todos los registros de un artículo sólo se realizase el cálculo de existencia y valoración de almacén una vez, ya que si se lanza por cada registro el número de veces que es modificado cada registro es el resultado de un cálculo factorial, lo que supone una gran pérdida de rendimiento en la ejecución de estos procesos.[/pl_alertbox]

2. Planteando la solución

Desde el punto de vista de teórico la solución es muy sencilla. Evitar que se ejecuten los triggers y actualizaciones siempre, y que sólo se ejecuten cuando nosotros lo deseemos.

Desde el punto de vista práctico parece en principio sencillo ya que las actualizaciones tienen una propiedad «condición» que permite indicar la fórmula a calcular con la condición que debe cumplirse para su ejecución, y los triggers son código en el podemos también usar sentencias de condición para evitar su ejecución. El problema aún así persiste ya que la condición para que no se ejecuten debe ser dinámica, es decir, no depende de los datos del registro sino que depende de las circunstancias en las que se producen las operaciones de alta, baja o modificación. Es decir, desde ciertos procesos, funciones o formularios sí deben ejecutarse y desde otros no.

3. Programando la solución

La solución pasa por conseguir que el registro sea «consciente» de si deben o no ejecutarse los triggers y actualizaciones, y que pase esa información a los triggers y actualizaciones para que actúen en consecuencia. Eso lo vamos a conseguir realizando los siguientes pasos:

  1. Añadir en la tabla un campo booleano, por ejemplo #CAL_ARR (Calcular datos arrastrados).
     
  2. Añadir en la tabla una variable local booleana, por ejemplo #CAL_ARR (Calcular datos arrastrados).
     
  3. En los triggers anteriores a alta, baja o modificación añadiremos el siguiente código para controlar si el campo booleano llega con el valor 1, en cuyo caso lo que hacemos es poner a 1 la variable local que será la que usemos a partir de este momento para condicionar la ejecución en triggers y actualizaciones, y el campo a 0 para evitar cualquier conflicto con un bucle infinito de actualizaciones en cascada.
     Cálculo de arrastrados - trigger anterior 
  4. Ahora sólo nos queda usar la variable local para controlar los componentes de actualización y el código de los triggers que deseamos ejecutar.
     Cálculo de arrastrados - trigger posterior
     Actualizaciones y arrastrados con condición dinámica en Velneo
     
  5. Ahora sólo queda que cuando vayas a crear, modificar o eliminar un registro de esta tabla, tanto desde un formulario, como de un manejador de evento, función, proceso, etc. pongas el valor del campo #CAL_ARR a 1 (si deseas que se ejecuten las actualizaciones y los cálculos arrastrados) o dejarlo a 0 (si deseas que no se ejecuten las actualizaciones y los cálculos arrastrados). Es importante que evites poner a 1 el valor de este campo en un trigger pues por error puedes llegar a provocar un bucle infinito o un desbordamiento del stack.
     

4. Conclusión

Práctico y sencillo de programar, podrás optimizar tu aplicación para que ejecuten los bucles de actualización de cálculos arrastrados y las actualizaciones el menor número de veces posible, independientemente de que las operaciones en la tabla se lancen desde objetos de interfaz, procesos en primer plano o en el servidor. Desgraciadamente en Velneo 6x no contamos con variables locales a nivel de tabla por lo que no podemos utilizar esta técnica.

Nota:

Si tu tabla tiene millones de registros y no te gusta usar un byte para obtener esta funcionalidad también puedes utilizar otro campo de la tabla donde puedas grabar al principio o al final del mismo un carácter o etiqueta que te identifique que se deben ejecutar los arrastrados y las actualizaciones. Por ejemplo, utilizar un campo #REF (Referencia) en el que pondríamos al principio de su contenido el símbolo «#». En el trigger anterior si aparece ese símbolo actualizamos el campo referencia quitándoselo y poniendo a 1 la variable local para ejecutar los arrastrados, de esta forma nos ahorramos un campo.

Scroll al inicio