The activation of a trigger results in the running of its associated triggered action. Every trigger has exactly one triggered action which, in turn, has two components:
The triggered action condition defines whether or not the set of triggered statements are performed for the row or for the statement for which the triggered action is executing. The set of triggered statements define the set of actions performed by the trigger in the database as a consequence of its event having occurred.
For example, the following trigger action specifies that the set of triggered SQL statements should only be activated for rows in which the value of the on_hand column is less than ten per cent of the value of the max_stocked column. In this case, the set of triggered SQL statements is the invocation of the issue_ship_request function.
CREATE TRIGGER REORDER AFTER UPDATE OF ON_HAND, MAX_STOCKED ON PARTS REFERENCING NEW AS N_ROW FOR EACH ROW MODE DB2SQL WHEN (N_ROW.ON_HAND < 0.10 * N_ROW.MAX_STOCKED) BEGIN ATOMIC VALUES(ISSUE_SHIP_REQUEST(N_ROW.MAX_STOCKED - N_ROW.ON_HAND, N_ROW.PARTNO)); END
As explained in Triggered Action, the triggered action condition is an optional clause of the triggered action which specifies a search condition that must evaluate to true to run SQL statements within the triggered action. If the WHEN clause is omitted, then the SQL statements within the triggered action are always executed.
The triggered action condition is evaluated once for each row if the trigger is a FOR EACH ROW trigger, and once for the statement if the trigger is a FOR EACH STATEMENT trigger.
This clause provides further control that you can use to fine tune the actions activated on behalf of a trigger. An example of the usefulness of the WHEN clause is to enforce a data dependent rule in which a triggered action is activated only if the incoming value falls inside or outside of a certain range.
The set of triggered SQL statements carries out the real actions caused by activating a trigger. As described previously, not every SQL operation is meaningful in every trigger. Depending on whether the trigger activation time is BEFORE or AFTER, different kinds of operations may be appropriate as a triggered SQL statement.
For a list of triggered SQL statements, and additional information on BEFORE and AFTER triggers, refer to the SQL Reference.
In most cases, if any triggered SQL statement returns a negative return code, the triggering SQL statement together with all trigger and referential constraint actions are rolled back, and an error is returned: SQLCODE -723 (SQLSTATE 09000). The trigger name, SQLCODE, SQLSTATE and many of the tokens from the failing triggered SQL statement are returned. Error conditions occurring when triggers are running that are critical or roll back the entire unit of work are not returned using SQLCODE -723 (SQLSTATE 09000).
Functions, including user-defined functions (UDFs), may be invoked within a triggered SQL statement. Consider the following example:,
CREATE TRIGGER REORDER AFTER UPDATE OF ON_HAND, MAX_STOCKED ON PARTS REFERENCING NEW AS N_ROW FOR EACH ROW MODE DB2SQL WHEN (N_ROW.ON_HAND < 0.10 * N_ROW.MAX_STOCKED) BEGIN ATOMIC VALUES (ISSUE_SHIP_REQUEST (N_ROW.MAX_STOCKED - N_ROW.ON_HAND, N_ROW.PARTNO)); END
When a triggered SQL statement contains a function invocation with an unqualified function name, the function invocation is resolved based on the function path at the time of creation of the trigger. For details on the resolution of functions, refer to the SQL Reference.
UDFs are written in either the C or C++ programming language. This enables control of logic flows, error handling and recovery, and access to system and library functions. (See Writing User-Defined Functions (UDFs) and Methods for a description of UDFs.) This capability allows a triggered action to perform non-SQL types of operations when a trigger is activated. For example, such a UDF could send an electronic mail message and thereby act as an alert mechanism. External actions, such as messages, are not under commit control and will be run regardless of success or failure of the rest of the triggered actions.
Also, the function can return an SQLSTATE that indicates an error has occurred which results in the failure of the triggering SQL statement. This is one method of implementing user-defined constraints. (Using a SIGNAL SQLSTATE statement is the other.) In order to use a trigger as a means to check complex user-defined constraints, you can use the RAISE_ERROR built-in function in a triggered SQL statement. This function can be used to return a user-defined SQLSTATE (SQLCODE -438) to applications. For details on invocation and use of this function, refer to the SQL Reference.
For example, consider some rules related to the HIREDATE column of the EMPLOYEE table, where HIREDATE is the date that the employee starts working.
The following trigger handles all of these rules on INSERT:
CREATE TRIGGER CHECK_HIREDATE NO CASCADE BEFORE INSERT ON EMPLOYEE REFERENCING NEW AS NEW_EMP FOR EACH ROW MODE DB2SQL BEGIN ATOMIC VALUES CASE WHEN NEW_EMP.HIREDATE < CURRENT DATE THEN RAISE_ERROR('85001', 'HIREDATE has passed') WHEN NEW_EMP.HIREDATE - CURRENT DATE > 10000. THEN RAISE_ERROR('85002', 'HIREDATE too far out') WHEN NEW_EMP.HIREDATE - CURRENT DATE > 600. THEN SEND_MOTE('persmgr',NEW_EMP.EMPNO,'late.txt') END; END