The CREATE TRIGGER statement defines a trigger at the current server.
This statement can be embedded in an application program or issued interactively. It is an executable statement that can be dynamically prepared.
The privileges held by the authorization ID of the statement must include at least one of the following:
The privileges held by the authorization ID of the statement must include at least one of the following:
In addition, the privileges held by the authorization ID of the statement must include at least one of the following:
If SQL names are specified, and a user profile exists that has the same name as the library into which the trigger is created, and the name is different from the authorization ID of the statement, then the privileges held by the authorization ID of the statement must include at least one of the following:
For information on the system authorities corresponding to SQL privileges, see Corresponding System Authorities When Checking Privileges to a Table or View.
.-NO CASCADE-. >>-CREATE TRIGGER--trigger-name--+-+------------+--BEFORE-+-----> +-AFTER------------------+ '-INSTEAD OF-------------' >--+-INSERT------------------------------+--ON--+-table-name-+--> +-DELETE------------------------------+ '-view-name--' '-UPDATE--+-------------------------+-' | .-,---------------. | | V | | '-OF------column-name---+-' >--+-------------------------------------------------------------------+--> | .--------------------------------------------------. | | V .-ROW-. .-AS-. (1) | | '-REFERENCING----+-OLD--+-----+--+----+--correlation-name--+------+-' | .-ROW-. .-AS-. | +-NEW--+-----+--+----+--correlation-name--+ | .-AS-. | +-+-OLD TABLE-+--+----+--table-identifier-+ | '-OLD_TABLE-' | | .-AS-. | '-+-NEW TABLE-+--+----+--table-identifier-' '-NEW_TABLE-' .-FOR EACH STATEMENT-. .-MODE DB2SQL-. >--+--------------------+--+-------------+--triggered-action--->< '-FOR EACH ROW-------' '-MODE DB2ROW-'
triggered-action: |--+----------------------+--+------------------------------+----SQL-trigger-body----| '-SET OPTION-statement-' '-WHEN--(--search-condition--)-' SQL-trigger-body: |--+-SQL-control-statement-----------------------+--------------| +-fullselect----------------------------------+ +-ALLOCATE DESCRIPTOR-statement---------------+ +-ALTER PROCEDURE (External)-statement--------+ +-ALTER SEQUENCE-statement--------------------+ +-ALTER TABLE-statement-----------------------+ +-COMMENT statement---------------------------+ +-CREATE ALIAS-statement----------------------+ +-CREATE DISTINCT TYPE-statement--------------+ +-CREATE FUNCTION (External Scalar)-statement-+ +-CREATE FUNCTION (External Table)-statement--+ +-CREATE INDEX-statement----------------------+ +-CREATE PROCEDURE (External)-statement-------+ +-CREATE SCHEMA-statement---------------------+ +-CREATE SEQUENCE-statement-------------------+ +-CREATE TABLE-statement----------------------+ +-CREATE VIEW-statement-----------------------+ +-DEALLOCATE DESCRIPTOR-statement-------------+ +-DECLARE GLOBAL TEMPORARY TABLE-statement----+ +-DELETE-statement----------------------------+ +-DESCRIBE-statement--------------------------+ +-DESCRIBE INPUT-statement--------------------+ +-DESCRIBE TABLE-statement--------------------+ +-DROP-statement------------------------------+ +-EXECUTE IMMEDIATE-statement-----------------+ +-GET DESCRIPTOR-statement--------------------+ +-GRANT-statement-----------------------------+ +-INSERT-statement----------------------------+ +-LABEL-statement-----------------------------+ +-LOCK TABLE-statement------------------------+ +-REFRESH TABLE-statement---------------------+ +-RELEASE-statement---------------------------+ +-RELEASE SAVEPOINT-statement-----------------+ +-RENAME-statement----------------------------+ +-REVOKE-statement----------------------------+ +-SAVEPOINT-statement-------------------------+ +-SELECT INTO-statement-----------------------+ +-SET CURRENT DEBUG MODE-statement------------+ +-SET CURRENT DEGREE-statement----------------+ +-SET DESCRIPTOR-statement--------------------+ +-SET ENCRYPTION PASSWORD-statement-----------+ +-SET PATH-statement--------------------------+ +-SET SCHEMA-statement------------------------+ +-SET TRANSACTION-statement-------------------+ '-UPDATE-statement----------------------------'
Names the trigger. The name, including the implicit or explicit qualifier, must not be the same as a trigger that already exists at the current server. QTEMP cannot be used as the trigger-name schema qualifier.
If SQL names were specified, the trigger will be created in the schema specified by the implicit or explicit qualifier.
If system names were specified, the trigger will be created in the schema that is specified by the qualifier. If not qualified, the trigger will be created in the same schema as the subject table.
If the trigger name is not a valid system name, or if a program with the same name already exists, the database manager will generate a system name. For information on the rules for generating a name, see Rules for Table Name Generation.
A DELETE trigger cannot be added to a table with a referential constraint of ON DELETE CASCADE.
An UPDATE trigger event cannot be added to a table with a referential constraint of ON DELETE SET NULL.
If an explicit column-name list is not specified, an update operation on any column of the subject table, including columns that are subsequently added with the ALTER TABLE statement, activates the triggered-action.
Each row affected by the triggering SQL operation is available to the triggered-action by qualifying columns with correlation-names specified as follows:
Only one OLD and one NEW correlation-name may be specified for a trigger. Only one OLD_TABLE and one NEW_TABLE table-identifier may be specified for a trigger. All of the correlation-names and table-identifiers must be unique from one another.
The OLD correlation-name and the OLD_TABLE table-identifier are valid only if the triggering event is either a delete operation or an update operation. For a delete operation, the OLD correlation-name captures the values of the columns in the deleted row, and the OLD_TABLE table-identifier captures the values in the set of deleted rows. For an update operation, OLD correlation-name captures the values of the columns of a row before the update operation, and the OLD_TABLE table-identifier captures the values in the set of updated rows.
The NEW ROW correlation-name and the NEW TABLE table-identifier are valid only if the triggering event is either an INSERT operation or an UPDATE operation. For both operations, the NEW ROW correlation-name captures the values of the columns in the inserted or updated row, and the NEW TABLE table-identifier captures the values in the set of inserted or updated rows. For before triggers, the values of the updated rows include the changes from any SET statements in the triggered-action of before triggers.
The OLD ROW and NEW ROW correlation-name variables cannot be modified in an AFTER trigger or INSTEAD OF trigger.
The tables below summarizes the allowable combinations of correlation variables and transition tables.
Granularity: FOR EACH ROW
MODE | Activation Time | Triggering Operation | Correlation Variables Allowed | Transition Tables Allowed |
---|---|---|---|---|
DB2ROW | BEFORE | DELETE | OLD | NONE |
INSERT | NEW | |||
UPDATE | OLD, NEW | |||
AFTER or INSTEAD OF | DELETE | OLD | ||
INSERT | NEW | |||
UPDATE | OLD, NEW | |||
DB2SQL | BEFORE | DELETE | OLD | |
INSERT | NEW | |||
UPDATE | OLD, NEW | |||
AFTER or INSTEAD OF | DELETE | OLD | OLD TABLE | |
INSERT | NEW | NEW TABLE | ||
UPDATE | OLD, NEW | OLD TABLE, NEW TABLE |
Granularity: FOR EACH STATEMENT
MODE | Activation Time | Triggering Operation | Correlation Variables Allowed | Transition Tables Allowed |
---|---|---|---|---|
DB2SQL | AFTER | DELETE | NONE | OLD TABLE |
INSERT | NEW TABLE | |||
UPDATE | OLD TABLE, NEW TABLE |
A transition variable that has a character data type inherits the CCSID of the column of the subject table. During the execution of the triggered-action, the transition variables are treated like variables. Therefore, character conversion might occur.
The temporary transition tables are read-only. They cannot be modified.
The scope of each correlation-name and each table-identifier is the entire trigger definition.
FOR EACH STATEMENT cannot be specified for a BEFORE or INSTEAD OF trigger.
FOR EACH STATEMENT cannot be specified for a MODE DB2ROW trigger.
MODE DB2ROW is valid for both the BEFORE and AFTER activation time.
SET OPTION DBGVIEW = *SOURCE
For more information,
see SET OPTION.
The options CLOSQLCSR, CNULRQD, COMPILEOPT, NAMING, and SQLCA are not allowed in the CREATE TRIGGER statement.
The options DATFMT, DATSEP, TIMFMT, and TIMSEP cannot be used if OLD ROW or NEW ROW is specified.
A call to a procedure that issues a CONNECT, SET CONNECTION, RELEASE, DISCONNECT, COMMIT, ROLLBACK, SET TRANSACTION, and SET RESULT SETS statement is not allowed in the triggered-action of a trigger.
If the trigger is a before trigger, then the SQL-trigger-body must not contain an INSERT, UPDATE, DELETE, ALTER TABLE, COMMENT, any CREATE statement, DECLARE GLOBAL TEMPORARY TABLE, DROP, any GRANT statement, LABEL, REFRESH TABLE, RENAME, or any REVOKE statement. It must not contain a reference to a procedure or function that modifies SQL data.
An UNDO handler is not allowed in a trigger.
All tables, views, aliases, distinct types, user-defined functions, and procedures referenced in the triggered-action must exist at the current server when the trigger is created. The table or view that an alias refers to must also exist when the trigger is created. This includes objects in library QTEMP. While objects in QTEMP can be referenced in the triggered-action, dropping those objects in QTEMP will not cause the trigger to be dropped.
The statements in the triggered-action can invoke a procedure or a user-defined function that can access a server other than the current server if the procedure or user-defined function runs in a different activation group.
Trigger ownership: If SQL names were specified:
If system names were specified, the owner of the trigger is the user profile or group user profile of the job executing the statement.
Trigger authority: The trigger program object authorities are:
Activating a trigger: Only insert, delete, or update operations can activate a trigger. A delete operation that occurs as a result of a referential constraint will not activate a trigger. Hence,
The activation of a trigger may cause trigger cascading. This is the result of the activation of one trigger that executes SQL statements that cause the activation of other triggers or even the same trigger again. The triggered actions may also cause updates as a result of the original modification, which may result in the activation of additional triggers. With trigger cascading, a significant chain of triggers may be activated causing significant change to the database as a result of a single delete, insert or update statement. The number of levels of cascading is limited to 200 or the maximum amount of storage allowed in the job or process, whichever comes first.
Adding triggers to enforce constraints: Adding a trigger to a table that already has rows in it will not cause the triggered actions to be executed. Thus, if the trigger is designed to enforce constraints on the data in the table, the data in the existing rows might not satisfy those constraints.
Multiple triggers: Multiple triggers that have the same triggering SQL operation and activation time can be defined on a table. The triggers are activated based on the mode and the order in which they were created:
For example, a MODE DB2ROW trigger that was created first is executed first, the MODE DB2ROW trigger that was created second is executed second.
A maximum of 300 triggers can be added to any given source table.
Adding columns to a subject table or a table referenced in the triggered action: If a column is added to the subject table after triggers have been defined, the following rules apply:
If a column is added to any table referenced by the SQL statements in the triggered-action, the new column is not accessible to the SQL statements until the trigger is recreated.
Dropping or revoking privileges on a table referenced in the triggered action: If an object such as a table, view or alias, referenced in the triggered-action is dropped, the access plans of the statements that reference the object will be rebuilt when the trigger is fired. If the object does not exist at that time, the corresponding INSERT, UPDATE or DELETE operation on the subject table will fail.
If a privilege that the creator of the trigger is required to have for the trigger to execute is revoked, the access plans of the statements that reference the object will be rebuilt when the trigger is fired. If the appropriate privilege does not exist at that time, the corresponding INSERT, UPDATE or DELETE operation on the subject table will fail.
Errors executing triggers: Errors that occur during the execution of SQL-trigger-body statements are returned using SQLSTATE 09000 and SQLCODE -723.
Special registers in triggers: The values of the special registers are saved before a trigger is activated and are restored on return from the trigger. The values of the special registers are inherited from the triggering SQL operation.
Performance considerations: Create the trigger under the isolation level that will most often by used by the application programs that cause the trigger to fire. The SET OPTION statement can be used to explicitly choose the isolation level.
ROW triggers (especially MODE DB2ROW triggers) perform much better than TABLE level triggers.
Transaction isolation: All triggers, when they are activated, perform a SET TRANSACTION statement unless the isolation level of the application program invoking the trigger is the same as the default isolation level of the trigger program. This is necessary so that all of the operations by the trigger are performed with the same isolation level as the application program that caused the trigger to be run. The user may put their own SET TRANSACTION statements in an SQL-control-statement in the SQL-trigger-body of the trigger. If the user places a SET TRANSACTION statement within the SQL-trigger-body of the trigger, then the trigger will run with the isolation level specified in the SET TRANSACTION statement, instead of the isolation level of the application program that caused the trigger to be run.
If the application program that caused a trigger to be activated, is running with an isolation level other than No Commit (COMMIT(*NONE) or COMMIT(*NC)), the operations within the trigger will be run under commitment control and will not be committed or rolled back until the application commits its current unit of work. If ATOMIC is specified in the SQL-trigger-body of the trigger, and the application program that caused the ATOMIC trigger to be activated is running with an isolation level of No Commit (COMMIT(*NONE) or COMMIT(*NC)), the operations within the trigger will not be run under commitment control. If the application that caused the trigger to be activated is running with an isolation level of No Commit (COMMIT(*NONE) or COMMIT(*NC)), then the operations of a trigger are written to the database immediately, and cannot be rolled back.
If both system triggers defined by the Add Physical File Trigger (ADDPFTRG) CL command and SQL triggers defined by the CREATE TRIGGER statement are defined for a table, it is recommended that the system triggers perform a SET TRANSACTION statement so that they are run with the same isolation level as the original application that caused the triggers to be activated. It is also recommended that the system triggers run in the Activation Group of the calling application. If system triggers run in a separate Activation Group (ACTGRP(*NEW)), then those system triggers will not participate in the unit of the work for the calling application, nor in the unit of work for any SQL triggers. System triggers that run in a separate Activation Group are responsible for committing or rolling back any database operations they perform under commitment control. Note that SQL triggers defined by the CREATE TRIGGER statement always run in the caller's Activation Group.
If the triggering application is running with commitment control, the operations of an SQL trigger, and any cascaded SQL triggers, will be captured into a sub-unit of work. If the operations of the trigger and any cascaded triggers are successful, the operations captured in the sub-unit of work will be committed or rolled back when the triggering application commits or rolls back its current unit of work. Any system triggers that run in the same Activation Group as the caller, and perform a SET TRANSACTION to the isolation level of the caller, will also participate in the sub-unit of work. If the triggering application is running without commit control, then the operations of the SQL triggers will also be run without commitment control.
If an application that causes a trigger to be activated, is running with an isolation level of No Commit (COMMIT(*NONE) or COMMIT(*NC)), and it issues an INSERT, UPDATE, or DELETE statement that encounters an error during the execution of the statement, no other the system and SQL triggers will still be activated following the error for that operation. However, some number of changes will already have been performed. If the triggering application is running with commitment control, the operations of any triggers that are captured in a sub-unit of work will be rolled back when the first error is encountered, and no additional triggers will be activated for the current INSERT, UPDATE, or DELETE statement.
Transition variable values and INSTEAD OF triggers: The initial values for new transition variables or new transition table columns visible in an INSTEAD OF INSERT trigger are set as follows:
The initial values for new transition variables or new transition table columns visible in an INSTEAD OF UPDATE trigger are set as follows:
Triggered actions in the catalog: At the time the trigger is created, the triggered-action is modified as a result of the CREATE TRIGGER statement:
The modified triggered-action is stored in the catalog.
Renaming or moving a table referenced in the triggered action: Any table (including the subject table) referenced in a triggered-action can be moved or renamed. However, the triggered-action will continue to reference the old name or schema. An error will occur if the referenced table is not found when the triggered-action is executed. Hence, you should drop the trigger and then re-create the trigger so that it refers to the renamed or moved table.
Datetime considerations: If OLD ROW or NEW ROW is specified, the date or time constants and the string representation of dates and times in variables that are used in SQL statements in the triggered-action must have a format of ISO, EUR, JIS, USA, or must match the date and time formats specified when the table was created if it was created using DDS and the CRTPF CL command. If the DDS specifications contain multiple different date or time formats, the trigger cannot be created.
Operations that invalidate triggers: An inoperative trigger is a trigger that is no longer available to be activated. If a trigger becomes invalid, no INSERT, UPDATE, or DELETE operations will be allowed on the subject table or view. A trigger becomes invalid if:
An invalid trigger must first be dropped before it can be recreated by issuing a CREATE TRIGGER statement. Note that dropping and recreating a trigger will affect the activation order of a trigger if multiple triggers for the same triggering operation and activation time are defined for the subject table.
Trigger program object: When a trigger is created, SQL creates a temporary source file that will contain C source code with embedded SQL statements. A program object is then created using the CRTPGM command. The SQL options used to create the program are the options that are in effect at the time the CREATE TRIGGER statement is executed. The program is created with ACTGRP(*CALLER).
The program is created with STGMDL(*SNGLVL). If the trigger runs on behalf of an application that uses STGMDL(*TERASPACE) and also uses commitment control, the entire application will need to run under a job scoped commitment definition (STRCMTCTL CMTSCOPE(*JOB)).
The trigger will execute with the adopted authority of the owner of the trigger.
Example 1: Create two triggers that track the number of employees that a company manages. The triggering table is the EMPLOYEE table, and the triggers increment and decrement a column with the total number of employees in the COMPANY_STATS table. The COMPANY_STATS table has the following properties:
CREATE TABLE COMPANY_STATS (NBEMP INTEGER, NBPRODUCT INTEGER, REVENUE DECIMAL(15,0))
This example uses row triggers to maintain summary data in another table.
Create the first trigger, NEW_HIRE, so that it increments the number of employees each time a new person is hired; that is, each time a new row is inserted into the EMPLOYEE table, increase the value of column NBEMP in table COMPANY_STATS by 1.
CREATE TRIGGER NEW_HIRE AFTER INSERT ON EMPLOYEE FOR EACH ROW MODE DB2SQL UPDATE COMPANY_STATS SET NBEMP = NBEMP + 1
Create the second trigger, FORM_EMP, so that it decrements the number of employees each time an employee leaves the company; that is, each time a row is deleted from the table EMPLOYEE, decrease the value of column NBEMP in table COMPANY_STATS by 1.
CREATE TRIGGER FORM_EMP AFTER DELETE ON EMPLOYEE FOR EACH ROW MODE DB2SQL BEGIN ATOMIC UPDATE COMPANY_STATS SET NBEMP = NBEMP - 1; END
Example 2: Create a trigger, REORDER, that invokes user-defined function ISSUE_SHIP_REQUEST to issue a shipping request whenever a parts record is updated and the on-hand quantity for the affected part is less than 10% of its maximum stocked quantity. User-defined function ISSUE_SHIP_REQUEST orders a quantity of the part that is equal to the part's maximum stocked quantity minus its on-hand quantity. The function eliminates any duplicate requests to order the same PARTNO and sends the unique order to the appropriate supplier.
This example also shows how to define the trigger as a statement trigger instead of a row trigger. For each row in the transition table that evaluates to true for the WHERE clause, a shipping request is issued for the part.
CREATE TRIGGER REORDER AFTER UPDATE OF ON_HAND, MAX_STOCKED ON PARTS REFERENCING NEW_TABLE AS NTABLE FOR EACH STATEMENT MODE DB2SQL BEGIN ATOMIC SELECT ISSUE_SHIP_REQUEST(MAX_STOCKED - ON_HAND, PARTNO) FROM NTABLE WHERE ON_HAND < 0.10 * MAX_STOCKED; END
Example 3: Assume that table EMPLOYEE contains column SALARY. Create a trigger, SAL_ADJ, that prevents an update to an employee's salary that exceeds 20% and signals such an error. Have the error that is returned with an SQLSTATE of 75001 and a description. This example shows that the SIGNAL SQLSTATE statement is useful for restricting changes that violate business rules.
CREATE TRIGGER SAL_ADJ AFTER UPDATE OF SALARY ON EMPLOYEE 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