Desencadenantes (TRIGGERS) iSeries

iSeries: Desencadenantes. Creación de un TRIGGER iSeries

Imaginad que necesitáis saber qué registros de artículos (es un ejemplo) se cambian, agregan o suprimen cada día en vuestra base instalada, para luego realizar tareas de comprobación sólo de esos registros. Se nos ocurre enseguida hacer una tabla que contengan los códigos de los registros modificados, añadidos o suprimidos durante el día y luego algún proceso por la noche que repase esta lista para nuestro propósito. Si es una aplicación pequeña es relativamente fácil localizar qué programas hacen esto, pero si la BI es muy grande el tema se vuelve bastante complicado, y ya no digamos si de algunos procesos no tenemos localizados los fuentes, entonces la tarea es imposible.

 

¿Seguro  que Imposible? No, aún hay esperanza, podemos usar los desencadenantes, TRIGGERS, de nuestro iSeries.

¿Qué es un desencadenante en el AS400?

Es una llamada automática a un programa, antes o después, de la inserción, adición o supresión de un registro en un fichero. De esta manera podemos realizar procesos de forma paralela sin modificar programas de la base instalada. Es un proceso rápido ya que no es un añadido al sistema operativo del iSeries sino que bebe del propio funcionamiento interno de los sistemas del iSeries (os daréis cuenta cuando expliquemos como usarlo).

Maravilloso, ¿verdad? Dejad que por un momento os devuelva a la tierra y os diga que sí, que lo parece, pero la primera vez que nos enfrentamos con un desencadenante algunos factores hacen que parezca complejo y mucha gente desiste de su uso. Más aún si intentamos leernos el REDBOOK de turno de IBM sobre el tema, más de 500 páginas. Para los que ya dominen el tema de los desencadenantes pueden encontrar dicha información en: Stored Procedures, Triggers, and User-Defined Functions on DB2 Universal Database for iSeries

 

Para los que aún no dominen el tema explicaremos los pasos mínimos necesarios para realizar un desencadenante (TRIGGER) sencillo pero completamente funcional.

El REDBOOK hablará de muchos pasos y muchos factores y variables pero principalmente son sólo tres pasos:

  • Definir el objetivo
  • Crear el programa receptor del evento
  • Activar el desencadenante

 

Vamos paso a paso a realizar nuestro TRIGGER

Definir primero el objetivo

Como todo en la vida, la programación no es una excepción, lo primero es saber dónde vamos. Definir el objetivo es importante para saber cómo tenemos que realizar el programa receptor del evento. No será igual si lo que queremos es controlar un tipo de cambios u otros, por ejemplo.

En nuestro ejemplo queremos saber cuando un artículo es añadido o modificado en nuestra BI para tareas de auditoría nocturna. Ya tenemos claro el objetivo, vamos a ver qué hemos de hacer.

Crear el programa receptor del evento

Esta es la parte compleja de la operación. ¿Cómo ha de ser un programa receptor de un desencadenante?

El primer paso es saber la longitud en bytes del fichero que vamos a colocar en TRIGGER así como la posición en la que está el campo o campos que necesitaremos recuperar para lo que necesitemos.

Para saber dichos datos usaremos el mandato DSPFFD

Añadir trigger a fichero iseries

En nuestro caso el fichero tiene una logitud de 142.

Y en cuanto a la posición del campo de código de artículo que nos interesa está en la posición 1 y tiene una longitud de 10.

Añadir trigger a fichero iseries

Una vez apuntados estos datos podemos realizar ya un programa que vaya a recibir un desencadenante. ¿Por qué digo recibir? Porque los programas que se usan como desencadenantes reciben automáticamente del OS400 dos parámetros. El primero de estos parámetros es un largo registro de 1050 posiciones con muchos valores, pero de los que no usaremos en este caso casi nada. Marcaré solamente lo que nos va a servir en este caso. Quedaría así la DS:

 

IPARM       DS

I                                        1  10 FNAME

I                                       11  20 LNAME

I                                       21  30 NNAME

I                                       31  31 TEVEN          

I                                       32  32 TTIME

I                                       33  33 CMTLCK

I                                       34  36 FILL1

I                                    B  37  400CCSID

I                                    B  37  400CCSID

I                                       41  48 FILL2

I                                    B  49  520OLDOFF

I                                    B  53  560OLDLEN

I                                    B  57  600ONOFF

I                                    B  61  640ONLEN

I                                    B  65  680NOFF

I                                    B  69  720NEWLEN

I                                    B  73  760NNOFF

I                                    B  77  800NNLEN

I                                       81 208 RESV3

I                                      209 336 OREC

I                                      337 340 OOMAP

I                                      341 468 RECORD

I                                      469 650 NNMAP

I                                      651 850 NNMA2

I                                      8511050 NNMA3

 

Y el segundo parámetro sería:

 

IPARM2       DS

I                                    B   1   40LENG

 

Y recibiríamos los parámetros así:

 

C           *ENTRY    PLIST

C                     PARM           PARM1

C                     PARM           PARM2

 

 

El parámetro TEVEN que he marcado en la DS le dirá al programa qué evento ha llamado al desencadenante, la inserción, la supresión o la modificación, y qué otro parámetro de la DS debemos usar:

C                     SELEC

C           TEVEN     WHEQ ‘1’                        ALTA

C                     Z-ADDNOFF      O       50

C           TEVEN     WHEQ ‘2’                        BAJA

C                     Z-ADDOLDOFF    O

C           TEVEN     WHEQ ‘3’                        MODIFICACION

C                     Z-ADDOLDOFF    O

C                     Z-ADDNOFF      O2      50

C                     ENDSL

C                     ADD  1         O

C                     ADD  1         O2

 

Y ahora 0 y O2 contienen el desplazamiento dentro de la DS donde están los datos del fichero que nos interesan y por ello necesitábamos saber la longitud del fichero, usaremos la siguiente función:

 

C           TEVEN     IFEQ ‘3’

C           142       SUBSTPARM1:O2  CAMIN     P

C                     ELSE

C           142       SUBSTPARM1:O   CAMIN     P

C                     ENDIF

 

Y habiendo antes definido la DS CAMIN de la siguiente manera para saber dónde estaba el código de artículo:

 

I            DS

I                                        1 142 CAMIN

I                                        1  100CET02

Ya tenemos el campo CET02 que en nuestro caso es el código de artículo modificado o insertado.

Luego con un sencillo:

 

C           CET02     CHAINETI02CNG             77

C   77                Z-ADDCET02     CET02C

C   77                WRITERETI02C

 

Nos guardaremos qué artículos se han modificado o insertado a lo largo del día para luego nuestro sistema de auditoría nocturna.

Activar el desencadenante

Si hemos realizado el paso anterior, que es el verdaderamente complejo, esta parte es muy sencilla. Sólo debemos usar el mandato de iSeries ADDPFTRG para añadir el desencadenante al fichero.

Usando este mandato, le diremos que antes o después del evento que nos interesa se ejecute el programa que hemos creado con anterioridad.

En nuestro caso nos interesa que después de la inserción en el fichero de artículos o después de cualquier modificación se active la llamada a nuestro programa que grabará un registro con el  código de artículo para una auditoría posterior. Por tanto tendremos que llamar a los siguientes dos mandatos:

 

ADDPFTRG

                FILE(MIBIBLIO/ARTICULOS)

                 TRGTIME(*AFTER)

                TRGEVENT(*INSERT)

                PGM(MIBIBLIO/MITRIGGER)   

 

Este primer mandato insertará la ejecución del programa después de la inserción de un registro en nuestra tabla de artículos.

Añadir trigger a fichero iseries

Y luego:

 

ADDPFTRG

                FILE(MIBIBLIO/ARTICULOS)

                 TRGTIME(*AFTER)

                TRGEVENT(*UPDATE)

                PGM(MIBIBLIO/MITRIGGER)   

 

Este segundo mandato insertará la ejecución del programa después de la modificación de un registro en nuestra tabla de artículos.

Y ya tenemos activado y funcionando el desencadenante, sin tocar ningún programa de nuestra BI podemos hacer procesos como éste.

A tener en cuenta

Una vez activado un desencadenante contra un fichero de nuestro iSeries no podremos modificar la estructura de este fichero o eliminarlo. Antes de ello hay que eliminar los TRIGGERS que tenga activado, usando para ello el mandato RMVPFTRG

 

 

                                      

 

 

 

 

 

 

5 comentarios
  1. David Lázaro
    David Lázaro Dice:

    Enhorabuena por tus artículos, Mario, son muy didácticos. Una observación sobre los triggers, que creo puede ser interesante: aunque el programa final siempre sea un RPG, es conveniente crear una CL intermedia (que será la que sea llamada por el evento), para así poder hacer cambios en el RPG “en caliente” sin tener que desactivar el trigger.
    Un saludo!

    • Mario Rodríguez
      Mario Rodríguez Dice:

      Sí, es una opción, cierto, pasar los dos parámetros primero por una CL y luego al RPG/RPG IV/RPG free para como dices tener más opciones a la hora de hacer cambios.

  2. Sergio L Puentes Valladares
    Sergio L Puentes Valladares Dice:

    La explicación es correcta, la única observación es el código algo antiguo (S36)
    C CET02 CHAINETI02CNG 77
    C 77 Z-ADDCET02 CET02C
    C 77 WRITERETI02C

    Más actual
    Rpg/400
    C CET02 CHAINETI02CNG 77
    C *IN77 IFEQ *ON
    C Z-ADDCET02 CET02C
    C WRITERETI02C
    C ENDIF

    RPG/ILE
    c CET02 CHAIN ETI02CNG
    c IF Not %Found(ETI02CNG)
    c Eval CET02C = CET02
    c WRITE RETI02C
    c EndIf

    Free/Rpg
    Chain(Cet02) ETI02CNG;
    if Not %Found(ETI02CNG);
    Cet02c = Cet02;
    Write ETI02C;
    EndIf;

    Asi sería mejor de acuerdo a la versión de RPG

    • Mario Rodríguez
      Mario Rodríguez Dice:

      Correcto, el fragmento de código que se ha puesto pertenece a una forma de programar más antigua, aunque no es S36, es RPG, válida, pero más antigua. Como bien explicas, cualquiera de las formas que detallas a continuación sería valida. Muchas gracias por la aportación

  3. Luis Giraldez
    Luis Giraldez Dice:

    Muy bueno, Mario. Llevo utilizando Triggers desde, aproximadamente, el año 2000, para hacer intercambios EDI como añadido a varios ERP en el iSeries, sin tocar el propio ERP, y funcionan de maravilla.

Los comentarios están desactivados.