$ cat create_trigger.sql
--#SET TERMINATOR #
DROP TRIGGER #
CREATE TRIGGER
AFTER [UPDATE|INSERT|DELETE] ON
REFERENCING [NEW|NEW_TABLE] AS N
[OLD|OLD_TABLE] AS O
FOR EACH [ROW|STATEMENT] MODE DB2SQL
BEGIN ATOMIC
{triggered-SQL-statement}
END#
$ db2 -f create_trigger.sql
Only one type could be provided, so if you want to listen on all modification types, you must create 3 triggers, one for INSERT, one for UPDATE, and one for DELETE.
NEW|NEW_TABLE could only be used with INSERT and UPDATE trigger-events.
OLD|OLD_TABLE could only be used with UPDATE and DELETE trigger-events.
NEW and OLD could only be used with FOR EACH ROW.
See following tables for details:
Granularity | Activation Time | Triggering SQL Operation | Transition Variables Allowe |
Transition Tables Allowed |
---|---|---|---|---|
FOR EACH ROW | BEFORE | INSERT | NEW | - |
UPDATE | OLD, NEW | - | ||
DELETE | OLD | - | ||
AFTER | INSERT | NEW | NEW TABLE | |
UPDATE | OLD, NEW | OLD TABLE, NEW TABLE | ||
DELETE | OLD | OLD TABLE | ||
OR EACH STATEMENT | BEFORE | INSERT | - | - |
UPDATE | - | - | ||
DELETE | - | - | ||
AFTER | INSERT | - | NEW TABLE | |
UPDATE | - | OLD TABLE, NEW TABLE | ||
DELETE | - | OLD TABLE |
Usually when "FOR EACH ROW", you should refer to NEW and OLD, not NEW_TABLE, and OLD_TABLE; this is reasonable cases; but since DB2 provides the transition variable NEW_TABLE and OLD_TABLE with "FOR EACH ROW", you can also use them of course; however, they must be used carefully, because where OLD_TABLE and NEW_TABLE means all the changed rows, not the current NEW and OLD; for example: if you create a trigger as:
CREATE TRIGGER TESTTRIGGER
AFTER UPDATE ON TESTTAB
REFERENCING NEW_TABLE AS N
OLD_TABLE AS O
FOR EACH ROW MODE DB2SQL
BEGIN ATOMIC
{refer to N and O}
END
And if an UPDATE statement update 10 rows data, this trigger will be fired 10 times, each time the transition variable NEW_TABLE and OLD_TABLE will contain 10 data rows.
A trigger body could include only SQL statements and built-in functions. So in a trigger body:
1. You cannot declare local variable
2. You cannot execute control statement, like IF, WHILE, etc
So if you want the trigger to perform actions or use logic that is not available in SQL statements or built-in functions, you need to write a stored procedure or a user defined function, and invoke it from the trigger body.
This is very bad user experience.
To invoke a user defined function using VALUES statement, like
VALUES YOUR_FUNCTION(N.EMPNO,O.SALARY,N.SALARY);
To invoke a stored procedure using CALL statement, like
CALL YOUR_PROCEDURE (N.EMPNO,O.SALARY,N.SALARY);