You are on page 1of 3

close w indow

P rint

iSeries EXTRA: Are You Trigger Happy?


January 2002 Jon Paris, Susan Gantner,

Because of changes with OS/400 V5R1, some trigger programs that worked perfectly prior to V5R1 will have problems after the upgrade. So this is a good time to examine your trigger programs to ensure they will still work properly after upgrading to the new release. While you're at it, you may want to update your coding techniques. One change makes it essential to utilize the offset values passed in the trigger buffer to locate the before and after record images. In past releases, you may have been able to get away with hard-coding the starting position of the before and after images, but changes made in V5R1 to support large object data types make this technique risky. The most important thing to look for in your trigger programs is the technique that you use to locate the record images. Before we get to the details of the offsets code, let's examine the way we should code the parameters needed for trigger programs. For explanations about the data found in the trigger buffer, refer to the "Triggering Automatic Events in Your Database" section of the Database Programming manual. D TrgBuffer DS D TFileName D TLibraryName D TMemberName D TEvent D TTime D TCommitLock D TFill01 D TCCSID D TRRN D TFill02 D TOldOffset D TOldLength D TOldNullOff D TOldNullLen D TNewOffset D TNewLength D TNewNullOff D TNewNullLen

10 10 10 1 1 1 3 10I 0 10I 0 10I 0 10I 0 10I 0 10I 0 10I 0 10I 0 10I 0 10I 0 10I 0

D TrgBufferLen

10I 0

Notice the use of the I (integer) data type in place of the older B (binary) data type for many of the trigger buffer values. The integer data type is more efficient and supports the full range of values possible, so it's a good idea to get into the habit of changing your B's to I's in RPG IV programs. You'll also need to change the length of the field-from 9 B to 10 I or 4 B to 5 I, assuming you're using length notation. The reasons are complex, and beyond the scope of this article. Next, let's examine the old and new record image data structure definitions. D OldRecord D NewRecord E DS E DS ExtName(MyFile) Prefix(O_) ExtName(MyFile)

Here we've simplified our coding and made it more change-resilient by using two externally described data structures based on the actual physical file record format and RPG IVs prefix globally renames all of the fields brought in from MyFile by appending the characters "O_" to the beginning of each field name. This allows us to use externally described data structures in both cases while maintaining unique names.

There are two common techniques to use the trigger buffer offset information to correctly locate the record images. One uses RPGs substring capability to copy the data from the trigger buffer to the appropriate data structure in the program. The other uses pointers to map the trigger buffer to the appropriate data structure. We prefer to use pointers, which are slightly more efficient and no more difficult to code by following our template - even if you don't understand pointers.

First, here's an example of using the substring technique to move the data to the externally described data structure used to map the data to the appropriate field names in the record. C Eval C Eval OldRecord = %Subst(TrgBuffer : ToldOffSet + 1) NewRecord = %Subst(TrgBuffer : TNewOffSet + 1)

These two lines copy the record images from the trigger buffer to the two data structures. Note: You must add one to the offset values, which are zero-based. In order to use the pointer method, we need to add the Based keyword to each data structure definition. This identifies the pointer that will be used to access the data. It's unnecessary to define the pointer fields themselves. The Based keyword implicitly defines them. Then supply a value to the pointers using the %Addr built-in function, as shown here: D OldRecord D E DS ExtName(MyFile) Prefix(O_) Based(OldRecPtr)

D NewRecord D C C

E DS ExtName(MyFile) Based(NewRecPtr)

Eval OldRecPtr = %ADDR(TrgBuffer)+TOldOffSet Eval NewRecPtr = %ADDR(TrgBuffer)+TNewOffSet

After these two lines of logic, the two data structures are now mapped directly to the data in the trigger buffer. Be sure to set the pointer using these Eval statements on each invocation of the trigger program, as the address value could change between invocations. Note: The code samples here can be used in the trigger program for any file. The only thing that must change is the value associated with the ExtName keyword. It makes for a simple template for writing new trigger programs. And even if the record format changes, you can simply recompile your trigger programs without code changes. Using either technique above, from this point on, the coding for the trigger logic is simple. Simply refer to the fields in the "after image" record by their original externally described names and fields in the "before image" record by appending an "O_" before the original field names. One word of caution: The code samples we used assume you have no null-capable fields in the file firing the trigger. If have null-capable fields, a few more lines of code must be added so you can access the null byte map associated with each record image. To see a sample program that includes support for null capable fields, view the code sample below.

I B M Sys tems M agazine is a trademark of I nternational B us ines s M ac hines C orporation. T he editorial c ontent of I B M Sys tems M agazine is plac ed on this webs ite by M SP T ec hM edia under lic ens e from I nternational Bus ines s M ac hines C orporation.

2 0 1 2 M SP C ommunic ations , I nc . A ll rights res erved.

You might also like