Example RPGLE Trigger Program


Apr 22

This morning, an old programming chum of mine was chatting to me about writing a program, that would be called everytime anything was updated in a given file (table) on the system. This action is very simple in the IBM-i world, using a technique called FILE TRIGGERS.

What is a Trigger?

A trigger is a program that is called whenever a row of data is updated, added or deleted. It has a generic input in the form of (a) a data structure holding various codes and also the the record that was updated and (b) the size of the data that was changed in (a).

So I dug out this old trigger (that I copied from somewhere a couple of years back) and just ran through my RPGLE Modernizer routine:

// Skeleton trigger program using RPGLE V7.1+

   copyright('| @SKELTRIG V001 2017.04.19')
   debug option(nodebugio:srcstmt)
   datfmt(iso-) timfmt(iso.)
   indent('| ');

dcl-pi *n;
   Trgbuffer likeds(trigger);
   Trgbufferlen int(10);

// Possible values for Event
dcl-c Insert '1';
dcl-c Delete '2';
dcl-c Update '3';
dcl-c Read '4';

// Possible values for Time
dcl-c After '1';
dcl-c Before '2';

// Possible values for Commitlocklev
dcl-c Cmtnone '0';
dcl-c Cmtchange '1';
dcl-c Cmtcs '2';
dcl-c Cmtall '3';

// Trigger buffer information
dcl-ds trigger qualified;
   File char(10);
   Library char(10);
   Member char(10);
   Event char(1);
   Time char(1);
   Commitlocklev char(1);
   *n char(3);
   Ccsid int(10);
   Rrn int(10);
   *n char(4);
   Befrecoffset int(10);
   Befreclen int(10);
   Befnulloffset int(10);
   Befnulllen int(10);
   Aftrecoffset int(10);
   Aftreclen int(10);
   Aftnulloffset int(10);
   Aftnulllen int(10);

// "Before" record image
dcl-s Befrecptr pointer;
dcl-ds Old extname('MYFILE') based(befrecptr) qualified end-ds;

//  "After" record image
dcl-s Aftrecptr pointer;
dcl-ds New extname('MYFILE') based(aftrecptr) qualified end-ds;

// Map trigger buffer into data structures
Befrecptr = %ADDR(Trgbuffer) + Trgbuffer.Befrecoffset;
Aftrecptr = %ADDR(Trgbuffer) + Trgbuffer.Aftrecoffset;

// Trigger processing goes here
// Refer to  Old field names with "old." qualification
// Refer to new field names with "new." qualification
  when trigger.event = Insert;
  // add some logic here for Insert processing
  // for example, something like this:
  if old.address <> new.address;
     // write some audit report detailing customers changed of address

  when trigger.event = Delete;
   // add some logic here for Delete processing
  when trigger.event = Update;
   // add some logic here for Update processing
  when trigger.event = Read;
   // add some logic here for Read processing

// Thats all Folks
*Inlr = *On;

Hope this works for ya! 🙂


About the Author

IBM i Software Developer, Digital Dad, AS400 Anarchist, RPG Modernizer, Alpha Nerd and Passionate Eater of Cheese and Biscuits. Nick Litten Dot Com is a mixture of blog posts that can be sometimes serious, frequently playful and probably down-right pointless all in the space of a day. Enjoy your stay, feel free to comment and in the words of the most interesting man in the world: Stay thirsty my friend.

%d bloggers like this: