Example RPGLE Trigger Program 

 April 22, 2017

By  NickLitten

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! šŸ™‚


IBM i Software Developer, Digital Dad, AS400 Anarchist, RPG Modernizer, Shameless Trekkie, Belligerent Nerd, Englishman Abroad 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 remember: If at first you don't succeed then skydiving probably isn't a hobby you should look into.

Nick Litten

related posts:

  • Hello Nick,

    My name is Antonio Mira. I am now working for AHP (Bob Wilson) and have come across some of your programs. I like your website. It has helped me immensely in my job so thank you for that. After a few years of not programming in the i now I’m back in it and rediscovering my love for the i and RPG. I do have a question for you. So, I’m trying to do is to call a program that accepts a data structure as a parameter. I can do that with no problem calling the program directly but what I want to do is submit that program. I just don’t know how I would do that with QCMDEXC being that the program is expecting a DS. Would I have to build the call string with all the parameters, one by one? The program that I’m calling is a report that I want to submit.

    This is what I have: (at the top of report prompt screen where the user enters report criteria)

    //DS for parameters for the report
    dcl-ds rptCriteriaDS qualified;
    @fromDate70 packed(7:0);
    @toDate70 packed(7:0);
    $XMIT char(1);
    $CRDSTS char(1);

    //prototype to call AI5007RP Credit Audit History report
    dcl-pr creditAudHistRpt extpgm(‘AI5007RP’);
    parmDS likeDS(rptCriteriaDS);

    Then, I simply call the report later on:
    //populate the DS


    So the question is how do I submit this report? Thank you for any advice you can provide.

  • {"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
    __CONFIG_colors_palette__{"active_palette":0,"config":{"colors":{"cff50":{"name":"Main Accent","parent":-1},"a344d":{"name":"Accent Transparent","parent":"cff50"}},"gradients":[]},"palettes":[{"name":"Default","value":{"colors":{"cff50":{"val":"var(--tcb-skin-color-0)"},"a344d":{"val":"rgba(46, 138, 229, 0.85)","hsl_parent_dependency":{"h":210,"l":0.54,"s":0.78}}},"gradients":[]},"original":{"colors":{"cff50":{"val":"rgb(0, 178, 255)","hsl":{"h":198,"s":1,"l":0.5}},"a344d":{"val":"rgba(0, 178, 255, 0.85)","hsl_parent_dependency":{"h":198,"s":1,"l":0.5}}},"gradients":[]}}]}__CONFIG_colors_palette__

    Get In Touch

    Iā€™m always looking for awesome input, feedback and critique!