One of the most significant database enhancements delivered in V3R1 is support for triggers. A trigger is a program that is attached to a specific database event?insert, update, or delete a record. What makes triggers interesting is the way they are initiated. The database manager calls the trigger program automatically every time the database event occurs. In other words, if you assign an insert trigger for a file, the designated trigger program will be called every time a record is added to the file.
Up to six triggers can be assigned to a file; they may be six different programs or the same program six times, or you can choose to assign a trigger for only some of the potential database transactions. Triggers can be assigned for add, update, and delete transactions. In each case, there can be up to two triggers: a before trigger and an after trigger.
Before and after refer to the relationship between triggers and other database events including referential integrity constraint checking and the actual write to the file (an insert, update, or delete). These relationships can be very complex. For more information, refer to the IBM Redbook, Database 2/400 Advanced Database Functions.
Almost any program can be a trigger. This gives triggers enormous power and flexibility. Of course, the flip side of this power is that, as the application designer, you are responsible for how the trigger program behaves. You can write a trigger program in any high-level language (e.g., RPG, COBOL, or C), and they can contain embedded SQL statements. You can also write trigger programs in CL. A simple example of a trigger is a program that faxes an order confirmation when a new order is added to the order header file.
I have found that understanding how triggers are assigned and how they are fired is an important first step in incorporating triggers into an AS/400 application design. This article covers the commands that allow you to assign, change, delete, and view triggers. With this information, you can create a simple application that fires a trigger. For example, you can use DFU to update a file and fire a trigger that sends a message to the user's message queue. Simplistic as this sounds, it helped me to understand the potential and the pitfalls of using triggers. I hope it will do the same for you. Here is a trigger program you can use to see how a trigger works.
PGM PARM(&BUFFER &BUFLEN) DCL VAR(&BUFFER) TYPE(*CHAR) LEN(200) DCL VAR(&BUFLEN) TYPE(*CHAR) LEN(4) DCL VAR(&USER) TYPE(*CHAR) LEN(10) RTVJOBA USER(&USER) SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) + MSGDTA('This message sent from TESTTRGPGM') + TOMSGQ(&USER) ENDPGM
The two parameters used by the program are required and are passed automatically by the operating system. For a simple program such as this, there's no need to do anything with them. In a subsequent article, I will discuss the more complex issues involved in writing a trigger program.
Triggers are assigned to a single file using the Add Physical File Trigger (ADDPFTRG) command shown in 1. I'll explain each parameter in detail.
Triggers are assigned to a single file using the Add Physical File Trigger (ADDPFTRG) command shown in Figure 1. I'll explain each parameter in detail.
FILE: This parameter designates the file the trigger is associated with.
TRGTIME: Trigger time specifies when the trigger program will be called in relation to the write to the file. Valid values are *BEFORE and *AFTER.
TRGEVENT: This parameter specifies the type of database event the trigger is associated with. Valid entries are *INSERT (add a record to the file), *UPDATE (change a record in the file), and *DELETE (delete a record from the file).
PGM: Use this parameter to specify the program that is called when the trigger event occurs. The program must exist before it can be assigned through the ADDPFTRG command. The TRGTIME parameter determines the timing of the call.
RPLTRG: Use this optional parameter to replace an existing trigger for the same database event and timing (e.g., replace the before insert trigger with a new trigger program). This allows ADDPFTRG to function as either an add or a change command. The default value is *NO. If you choose a value of *NO and a trigger already exists for the event and time specified (e.g., before insert), the ADDPFTRG command will fail.
TRGUPDCOND: This optional parameter is only used for update triggers. If it is set to *CHANGE, the trigger will fire only if data in the record is actually modified; if the record is rewritten with the same values as before, the trigger will not fire. The default is *ALWAYS, which causes the trigger program to be called even when the data is not modified.
The trigger still won't fire if the record isn't actually written. This can happen if the program that updates the file checks to see if any changes have been made before issuing the write of the record. For example, DFU detects whether or not any field has been modified and does not write to the file if no changes were made. The result is that the trigger will not fire from DFU unless data is actually modified?even if TRGUPDCOND is set to *ALWAYS.
The only other OS/400 command directly associated with triggers is the Remove Physical File Trigger (RMVPFTRG) command (see 2). This command removes a single trigger, all triggers for a file, or a group of related triggers.
The only other OS/400 command directly associated with triggers is the Remove Physical File Trigger (RMVPFTRG) command (see Figure 2). This command removes a single trigger, all triggers for a file, or a group of related triggers.
The Display File Description (DSPFD) command includes trigger information if you specify TYPE(*ALL) or TYPE(*TRG). 3 contains an example of a DSPFD command showing trigger information.
The Display File Description (DSPFD) command includes trigger information if you specify TYPE(*ALL) or TYPE(*TRG). Figure 3 contains an example of a DSPFD command showing trigger information.
For each trigger assigned to the file (maximum six), this display provides the name of the trigger program and the library it's stored in, the trigger event and the trigger time (before or after), and the trigger update condition (*ALWAYS or *CHANGE) if applicable.
Triggers are one of the best database features added to OS/400 in V3R1. I encourage you to begin experimenting with simple triggers using the commands presented in this article. In future articles, we'll discuss design considerations for assigning and writing trigger programs.
Sharon Hoffman is the editor of Midrange Computing.
Database 2/400 Advanced Database Functions (GG24-4249, CD-ROM GG244249).
OS/400 CL Reference V3R1 (SC41-3722, CD-ROM QBKAUP00).
OS/400 DB2/400 Database Programming V3R1 (SC41-3701, CD-ROM QBKAUC00).