Creating a trigger

A trigger is a set of SQL statements that execute when a certain event occurs in a table or view. Use triggers to control changes in DB2® databases. Triggers are more powerful than constraints because they can monitor a broader range of changes and perform a broader range of actions.

About this task

Using triggers for active data:

For example, a constraint can disallow an update to the salary column of the employee table if the new value is over a certain amount. A trigger can monitor the amount by which the salary changes, as well as the salary value. If the change is above a certain amount, the trigger might substitute a valid value and call a user-defined function to send a notice to an administrator about the invalid update.

Triggers also move application logic into DB2, which can result in faster application development and easier maintenance. For example, you can write applications to control salary changes in the employee table, but each application program that changes the salary column must include logic to check those changes. A better method is to define a trigger that controls changes to the salary column. Then DB2 does the checking for any application that modifies salaries.

Example of creating and using a trigger:

Triggers automatically execute a set of SQL statements whenever a specified event occurs. These SQL statements can perform tasks such as validation and editing of table changes, reading and modifying tables, or invoking functions or stored procedures that perform operations both inside and outside DB2.

You create triggers using the CREATE TRIGGER statement. The following figure shows an example of a CREATE TRIGGER statement.

                 1 
CREATE TRIGGER REORDER
    2      3                                4 
  AFTER UPDATE OF ON_HAND, MAX_STOCKED ON PARTS
                      5 
  REFERENCING NEW AS N_ROW
   6 
  FOR EACH ROW MODE DB2SQL
   7 
  WHEN (N_ROW.ON_HAND < 0.10 * N_ROW.MAX_STOCKED)
   8 
  BEGIN ATOMIC
  CALL ISSUE_SHIP_REQUEST(N_ROW.MAX_STOCKED -
                                N_ROW.ON_HAND,
                                N_ROW.PARTNO);
  END
The parts of this trigger are:
 1 
Trigger name (REORDER)
 2 
Trigger activation time (AFTER)
 3 
Triggering event (UPDATE)
 4 
Subject table name (PARTS)
 5 
New transition variable correlation name (N_ROW)
 6 
Granularity (FOR EACH ROW)
 7 
Trigger condition (WHEN…)
 8 
Trigger body (BEGIN ATOMIC…END;)

When you execute this CREATE TRIGGER statement, DB2 creates a trigger package called REORDER and associates the trigger package with table PARTS. DB2 records the timestamp when it creates the trigger. If you define other triggers on the PARTS table, DB2 uses this timestamp to determine which trigger to activate first when the triggering event occurs. The trigger is now ready to use.

After DB2 updates columns ON_HAND or MAX_STOCKED in any row of table PARTS, trigger REORDER is activated. The trigger calls a stored procedure called ISSUE_SHIP_REQUEST if, after a row is updated, the quantity of parts on hand is less than 10% of the maximum quantity stocked. In the trigger condition, the qualifier N_ROW represents a value in a modified row after the triggering event.

When you no longer want to use trigger REORDER, you can delete the trigger by executing the statement:
DROP TRIGGER REORDER;

Executing this statement drops trigger REORDER and its associated trigger package named REORDER.

If you drop table PARTS, DB2 also drops trigger REORDER and its trigger package.

Parts of a trigger:

A trigger contains the following parts:
  • trigger name
  • subject table
  • trigger activation time
  • triggering event
  • granularity
  • correlation names for transition variables and transition tables
  • triggered action that consists of an optional search condition and a trigger body

Trigger name:

Use an ordinary identifier to name your trigger. You can use a qualifier or let DB2 determine the qualifier. When DB2 creates a trigger package for the trigger, it uses the qualifier for the collection ID of the trigger package. DB2 uses these rules to determine the qualifier:
  • If you use static SQL to execute the CREATE TRIGGER statement, DB2 uses the authorization ID in the bind option QUALIFIER for the package that contains the CREATE TRIGGER statement. If the bind command does not include the QUALIFIER option, DB2 uses the owner of the package.
  • If you use dynamic SQL to execute the CREATE TRIGGER statement, DB2 uses the authorization ID in special register CURRENT SCHEMA.

Subject table or view:

When you perform an insert, update, or delete operation on this table or view, the trigger is activated. You must name a local table or view in the CREATE TRIGGER statement. You cannot define a trigger on a catalog table.

Trigger activation time:

The two choices for trigger activation time are NO CASCADE BEFORE and AFTER. NO CASCADE BEFORE means that the trigger is activated before DB2 makes any changes to the subject table, and that the triggered action does not activate any other triggers. AFTER means that the trigger is activated after DB2 makes changes to the subject table and can activate other triggers. Triggers with an activation time of NO CASCADE BEFORE are known as before triggers. Triggers with an activation time of AFTER are known as after triggers.

Triggering event:

Every trigger is associated with an event. A trigger is activated when the triggering event occurs in the subject table or view. The triggering event is one of the following SQL operations:
  • insert
  • update
  • delete

A triggering event can also be an update or delete operation that occurs as the result of a referential constraint with ON DELETE SET NULL or ON DELETE CASCADE.

A trigger can be activated by a MERGE statement for insert and update operations.

Triggers are not activated as the result of updates made to tables by DB2 utilities, with the exception of the LOAD utility when it is specified with the RESUME YES and SHRLEVEL CHANGE options.

When the triggering event for a trigger is an update operation, the trigger is called an update trigger. Similarly, triggers for insert operations are called insert triggers, and triggers for delete operations are called delete triggers.

The SQL statement that performs the triggering SQL operation is called the triggering SQL statement. Each triggering event is associated with one subject table or view and one SQL operation.

The following trigger is defined with an insert triggering event:
CREATE TRIGGER NEW_HIRE
  AFTER INSERT ON EMP
  FOR EACH ROW MODE DB2SQL
  BEGIN ATOMIC
    UPDATE COMPANY_STATS SET NBEMP = NBEMP + 1;
  END

If the triggering SQL operation is an update operation, the event can be associated with specific columns of the subject table. In this case, the trigger is activated only if the update operation updates any of the specified columns.

The following trigger, PAYROLL1, which invokes user-defined function named PAYROLL_LOG, is activated only if an update operation is performed on the SALARY or BONUS column of table PAYROLL:
CREATE TRIGGER PAYROLL1
  AFTER UPDATE OF SALARY, BONUS ON PAYROLL
  FOR EACH STATEMENT MODE DB2SQL
  BEGIN ATOMIC
    VALUES(PAYROLL_LOG(USER, 'UPDATE', CURRENT TIME, CURRENT DATE));
  END

Granularity:

The triggering SQL statement might modify multiple rows in the table. The granularity of the trigger determines whether the trigger is activated only once for the triggering SQL statement or once for every row that the SQL statement modifies. The granularity values are:
  • FOR EACH ROW
    The trigger is activated once for each row that DB2 modifies in the subject table or view. If the triggering SQL statement modifies no rows, the trigger is not activated. However, if the triggering SQL statement updates a value in a row to the same value, the trigger is activated. For example, if an UPDATE trigger is defined on table COMPANY_STATS, the following SQL statement will activate the trigger.
    UPDATE COMPANY_STATS SET NBEMP = NBEMP;
  • FOR EACH STATEMENT

    The trigger is activated once when the triggering SQL statement executes. The trigger is activated even if the triggering SQL statement modifies no rows.

Triggers with a granularity of FOR EACH ROW are known as row triggers. Triggers with a granularity of FOR EACH STATEMENT are known as statement triggers. Statement triggers can only be after triggers.

The following statement is an example of a row trigger:
CREATE TRIGGER NEW_HIRE
  AFTER INSERT ON EMP
  FOR EACH ROW MODE DB2SQL
  BEGIN ATOMIC
    UPDATE COMPANY_STATS SET NBEMP = NBEMP + 1;
  END
Trigger NEW_HIRE is activated once for every row inserted into the employee table.

Transition variables:

When you code a row trigger, you might need to refer to the values of columns in each updated row of the subject table or view. To do this, specify a correlation name (to use when referencing transition variables) in the REFERENCING clause of your CREATE TRIGGER statement. The two types of transition variables are:
  • Old transition variables capture the values of columns before the triggering SQL statement updates them. You can use the REFERENCING OLD clause to define a correlation name for referencing old transition variables for update and delete triggers.
  • New transition variables capture the values of columns after the triggering SQL statement updates them. You can use the REFERENCING NEW clause to define a correlation name for referencing new transition variables for update and insert triggers.

Transition variables can be referenced anywhere in an SQL statement where an expression or variable can be specified in triggers.

The following example uses transition variables and invocations of the IDENTITY_VAL_LOCAL function to access values that are assigned to identity columns.

Suppose that you have created tables T and S, with the following definitions:
CREATE TABLE T 
  (ID SMALLINT GENERATED BY DEFAULT AS IDENTITY (START WITH 100), 
   C2 SMALLINT, 
   C3 SMALLINT, 
   C4 SMALLINT);
CREATE TABLE S 
  (ID SMALLINT GENERATED ALWAYS AS IDENTITY,
   C1 SMALLINT);
Define a before insert trigger on T that uses the IDENTITY_VAL_LOCAL built-in function to retrieve the current value of identity column ID, and uses transition variables to update the other columns of T with the identity column value.
CREATE TRIGGER TR1
  NO CASCADE BEFORE INSERT
  ON T REFERENCING NEW AS N
  FOR EACH ROW MODE DB2SQL
  BEGIN ATOMIC
    SET N.C3 =N.ID;
    SET N.C4 =IDENTITY_VAL_LOCAL();
    SET N.ID =N.C2 *10;
    SET N.C2 =IDENTITY_VAL_LOCAL();
  END
Now suppose that you execute the following INSERT statement:
INSERT INTO S (C1) VALUES (5);
This statement inserts a row into S with a value of 5 for column C1 and a value of 1 for identity column ID. Next, suppose that you execute the following SQL statement, which activates trigger TR1:
INSERT INTO T (C2)
  VALUES (IDENTITY_VAL_LOCAL());
This insert statement, and the subsequent activation of trigger TR1, have the following results:
  • The INSERT statement obtains the most recent value that was assigned to an identity column (1), and inserts that value into column C2 of table T. 1 is the value that DB2 inserted into identity column ID of table S.
  • When the INSERT statement executes, DB2 inserts the value 100 into identity column ID column of C2.
  • The first statement in the body of trigger TR1 inserts the value of transition variable N.ID (100) into column C3. N.ID is the value that identity column ID contains after the INSERT statement executes.
  • The second statement in the body of trigger TR1 inserts the null value into column C4. By definition, the result of the IDENTITY_VAL_LOCAL function in the triggered action of a before insert trigger is the null value.
  • The third statement in the body of trigger TR1 inserts 10 times the value of transition variable N.C2 (10*1) into identity column ID of table T. N.C2 is the value that column C2 contains after the INSERT is executed.
  • The fourth statement in the body of trigger TR1 inserts the null value into column C2. By definition, the result of the IDENTITY_VAL_LOCAL function in the triggered action of a before insert trigger is the null value.

Transition tables:

If you want to refer to the entire set of rows that a triggering SQL statement modifies, rather than to individual rows, use a transition table. Like transition variables, a correlation name (to refer to the columns of the transition table) can appear in the REFERENCING clause of a CREATE TRIGGER statement. The names for those columns are the same as the name of the column in the table or view that the trigger is defined for. Transition tables are valid for both row triggers and statement triggers. The two types of transition tables are:
  • Old transition tables, specified with the OLD TABLE transition-table-name clause, capture the values of columns before the triggering SQL statement updates them. You can define old transition tables for update and delete triggers.
  • New transition tables, specified with the NEW TABLE transition-table-name clause, capture the values of columns after the triggering SQL statement updates them. You can define new transition variables for update and insert triggers.

The scope of old and new transition table names is the trigger body. If correlation names are specified for both old and new transition variables in the trigger, a reference to a transition variable must be qualified with the associated correlation name.

The following example accesses a new transition table to capture the set of rows that are inserted into the INVOICE table:
CREATE TRIGGER LRG_ORDR
  AFTER INSERT ON INVOICE
  REFERENCING NEW TABLE AS N_TABLE
  FOR EACH STATEMENT MODE DB2SQL
  BEGIN ATOMIC
    SELECT LARGE_ORDER_ALERT(CUST_NO,
    TOTAL_PRICE, DELIVERY_DATE)
    FROM N_TABLE WHERE TOTAL_PRICE > 10000;
  END

The SELECT statement in LRG_ORDER causes user-defined function LARGE_ORDER_ALERT to execute for each row in transition table N_TABLE that satisfies the WHERE clause (TOTAL_PRICE > 10000).

Triggered action:

When a trigger is activated, a triggered action occurs. Every trigger has one triggered action, which consists of an optional trigger condition and a trigger body.

Trigger condition:

If you want the triggered action to occur only when certain conditions are true, code a trigger condition. A trigger condition is similar to a predicate in a SELECT, except that the trigger condition begins with WHEN, rather than WHERE. If you do not include a trigger condition in your triggered action, the trigger body executes every time the trigger is activated.

For a row trigger, DB2 evaluates the trigger condition once for each modified row of the subject table. For a statement trigger, DB2 evaluates the trigger condition once for each execution of the triggering SQL statement.

If the trigger condition of a before trigger has a fullselect, the fullselect cannot reference the subject table.

The following example shows a trigger condition that causes the trigger body to execute only when the number of ordered items is greater than the number of available items:
CREATE TRIGGER CK_AVAIL
  NO CASCADE BEFORE INSERT ON ORDERS
  REFERENCING NEW AS NEW_ORDER
  FOR EACH ROW MODE DB2SQL
  WHEN (NEW_ORDER.QUANTITY >
    (SELECT ON_HAND FROM PARTS
     WHERE NEW_ORDER.PARTNO=PARTS.PARTNO))
     BEGIN ATOMIC
       VALUES(ORDER_ERROR(NEW_ORDER.PARTNO,
         NEW_ORDER.QUANTITY));
     END

Trigger body:

Start of changeIn the trigger body, you code the SQL statements that you want to execute whenever the trigger condition is true. If the trigger body consists of more than one statement, it must begin with BEGIN ATOMIC and end with END. You cannot include host variables or parameter markers in your trigger body.End of change

Start of changeThe statements that you can use in a trigger body depend on the activation time of the trigger. For a list of valid SQL statements for triggers, see Table 2. Allowable SQL statements under SQL-trigger-body in the CREATE TRIGGER topic.End of change

Because you can include INSERT, DELETEStart of change (searched)End of change, UPDATEStart of change (searched)End of change, and MERGE statements in your trigger body, execution of the trigger body might cause activation of other triggers. See Trigger cascading for more information.

Examples

Example 1: Define a trigger to increment the count of employees when a new employee is hired. The following example also explains how to determine why an SQL statement is allowed in the trigger.
   CREATE TRIGGER NEW_HIRE
      AFTER INSERT ON EMPLOYEE
      FOR EACH ROW MODE DB2SQL
      BEGIN ATOMIC
         1 
        UPDATE COMPANY_STATS SET NBEMP = NBEMP + 1;
      END

The UPDATE statement ( 1 ) is an SQL statement that is allowed because it is listed in Table 2. Allowable SQL statements.

The following list provides more detailed information about SQL statements that are valid in triggers:

  • fullselect, CALL, and VALUES

Use a fullselect or the VALUES statement in a trigger body to conditionally or unconditionally invoke a user-defined function. Use the CALL statement to invoke a stored procedure. See Invoking a stored procedure or user-defined function from a trigger for more information on invoking user-defined functions and stored procedures from triggers.

A fullselect in the trigger body of a before trigger cannot reference the subject table.

Example 2: Define a trigger to return an error condition and back out any changes that are made by the trigger, as well as actions that result from referential constraints on the subject table. Use the SIGNAL statement to indicate the error information to be returned. When DB2 executes the SIGNAL statement, it returns an SQLCA to the application with SQLCODE -438. The SQLCA also includes the following values, which you supply in the SIGNAL statement:
  • A 5-character value that DB2 uses as the SQLSTATE
  • An error message that DB2 places in the SQLERRMC field
In the following example, the SIGNAL statement causes DB2 to return an SQLCA with SQLSTATE 75001 and terminate the salary update operation if an employee's salary increase is over 20%:
CREATE TRIGGER SAL_ADJ
  BEFORE UPDATE OF SALARY ON EMP
  REFERENCING OLD AS OLD_EMP
  NEW AS NEW_EMP
  FOR EACH ROW MODE DB2SQL
  WHEN (NEW_EMP.SALARY > (OLD_EMP.SALARY * 1.20))
  BEGIN ATOMIC
    SIGNAL SQLSTATE '75001'
      ('Invalid Salary Increase - Exceeds 20%');
  END
Example 3: Define a trigger to assign the current date to the HIRE_DATE column when a row is inserted into the EMP table. Because before triggers operate on rows of a table before those rows are modified, you cannot perform operations in the body of a before trigger that directly modify the subject table. You can, however, use the SET transition-variable statement to modify the values in a row before those values go into the table. For example, this trigger uses a new transition variable (NEW_VAR.HIRE_DATE) to assign today's date for the new employee's hire date:
CREATE TRIGGER HIREDATE
  NO CASCADE BEFORE INSERT ON EMP
  REFERENCING NEW AS NEW_VAR
  FOR EACH ROW MODE DB2SQL
  BEGIN ATOMIC
    SET NEW_VAR.HIRE_DATE = CURRENT_DATE;
  END
Related reference:
CREATE TRIGGER
LOAD