SQL$HELP_OLD72.HLB  —  CREATE  TRIGGER  Examples
    Example 1: Defining a cascading delete trigger

    The following SQL procedure shows a trigger from the sample
    personnel database that deletes rows in several tables before
    deleting a row in the EMPLOYEES table. Each associated employee
    row (from the tables that have foreign keys referring to the
    primary key in the employee row) is deleted. The employee
    identification number being deleted (00164) belongs to an
    employee who is also a manager; therefore, the MANAGER_ID column
    in the DEPARTMENTS table is set to null, as specified by the
    trigger.

    SQL> SET TRANSACTION READ WRITE;
    SQL> --
    SQL> -- Display the EMPLOYEE_ID_CASCADE_DELETE trigger
    SQL> -- in the sample database:
    SQL> --
    SQL> SHOW TRIGGER EMPLOYEE_ID_CASCADE_DELETE
         EMPLOYEE_ID_CASCADE_DELETE
     Source:
     EMPLOYEE_ID_CASCADE_DELETE
           BEFORE DELETE ON EMPLOYEES
           (DELETE FROM DEGREES D WHERE D.EMPLOYEE_ID =
            EMPLOYEES.EMPLOYEE_ID)
              FOR EACH ROW
           (DELETE FROM JOB_HISTORY JH WHERE JH.EMPLOYEE_ID =
            EMPLOYEES.EMPLOYEE_ID)
              FOR EACH ROW
           (DELETE FROM SALARY_HISTORY SH WHERE SH.EMPLOYEE_ID =
            EMPLOYEES.EMPLOYEE_ID)
              FOR EACH ROW
         ! Also, if an employee is terminated and that employee
         ! is the manager of a department, set the manager_id
         ! null for that department.
           (UPDATE DEPARTMENTS D  SET D.MANAGER_ID = NULL
            WHERE D.MANAGER_ID = EMPLOYEES.EMPLOYEE_ID)
              FOR EACH ROW
    SQL> --
    SQL> -- The EMPLOYEES table has a value of '00164'
    SQL> -- in the EMPLOYEE_ID column:
    SQL> --
    SQL> SELECT * FROM EMPLOYEES E WHERE E.EMPLOYEE_ID = '00164';
     EMPLOYEE_ID   LAST_NAME        FIRST_NAME   MIDDLE_INITIAL
       ADDRESS_DATA_1              ADDRESS_DATA_2         CITY
          STATE   POSTAL_CODE   SEX    BIRTHDAY      STATUS_CODE
     00164         Toliver          Alvin        A
       146 Parnell Place                                  Chocorua
          NH      03817         M      28-Mar-1947   1

    1 row selected
    SQL> --
    SQL> --
    SQL> -- The DEGREES table has two values of '00164'
    SQL> -- in the EMPLOYEE_ID column:
    SQL> --
    SQL> SELECT * FROM DEGREES D WHERE D.EMPLOYEE_ID = '00164';
     EMPLOYEE_ID   COLLEGE_CODE   YEAR_GIVEN   DEGREE   DEGREE_FIELD
     00164         PRDU                 1973   MA       Applied Math
     00164         PRDU                 1982   PhD      Statistics
    2 rows selected
    SQL> --
    SQL> --
    SQL> -- The JOB_HISTORY table has the value of '00164' in
    SQL> -- several rows in the EMPLOYEE_ID column:
    SQL> --
    SQL> SELECT * FROM JOB_HISTORY JH WHERE JH.EMPLOYEE_ID = '00164';
     EMPLOYEE_ID   JOB_CODE   JOB_START     JOB_END       DEPARTMENT_CODE
       SUPERVISOR_ID
     00164         DMGR       21-Sep-1981   NULL          MBMN
       00228

     00164         SPGM        5-Jul-1980   20-Sep-1981   MCBM
       00164

    2 rows selected
    SQL> --
    SQL> --
    SQL> -- The SALARY_HISTORY table has a value of '00164'
    SQL> -- in several rows in the EMPLOYEE_ID column:
    SQL> --
    SQL> SELECT * FROM SALARY_HISTORY SH WHERE SH.EMPLOYEE_ID = '00164';
     EMPLOYEE_ID   SALARY_AMOUNT   SALARY_START   SALARY_END
     00164            $26,291.00    5-Jul-1980     2-Mar-1981
     00164            $51,712.00   14-Jan-1983    NULL
     00164            $26,291.00    2-Mar-1981    21-Sep-1981
     00164            $50,000.00   21-Sep-1981    14-Jan-1983
    4 rows selected
    SQL> --
    SQL> --
    SQL> -- The DEPARTMENTS table has a value of '00164'
    SQL> -- in the MANAGER_ID column:
    SQL> --
    SQL> SELECT * FROM DEPARTMENTS D WHERE D.MANAGER_ID = '00164';
     DEPARTMENT_CODE   DEPARTMENT_NAME                  MANAGER_ID
       BUDGET_PROJECTED   BUDGET_ACTUAL
     MBMN              Board Manufacturing North        00164
                   NULL            NULL

    1 row selected
    SQL> --
    SQL> --
    SQL> -- Test the trigger by deleting the row with a value of '00164'
    SQL> -- in the EMPLOYEE_ID column from the EMPLOYEES table:
    SQL> --
    SQL> DELETE FROM EMPLOYEES E WHERE E.EMPLOYEE_ID = '00164';
    1 row deleted
    SQL> --
    SQL> -- The row with a value of '00164' in the EMPLOYEE_ID column
    SQL> -- was deleted from the EMPLOYEES table:
    SQL> --
    SQL> SELECT * FROM EMPLOYEES E WHERE E.EMPLOYEE_ID = '00164';
    0 rows selected
    SQL> --
    SQL> -- The rows with a value of '00164' in the EMPLOYEE_ID column
    SQL> -- were deleted from the DEGREES table:
    SQL> --
    SQL> SELECT * FROM DEGREES D WHERE D.EMPLOYEE_ID = '00164';
    0 rows selected
    SQL> --
    SQL> -- The rows with a value of '00164' in the EMPLOYEE_ID
    SQL> -- column were deleted from the JOB_HISTORY table:
    SQL> --
    SQL> SELECT * FROM JOB_HISTORY JH WHERE JH.EMPLOYEE_ID = '00164';
    0 rows selected
    SQL> --
    SQL> -- The rows with a value of '00164' in the EMPLOYEE_ID
    SQL> -- column were deleted from the SALARY_HISTORY table:
    SQL> --
    SQL> SELECT * FROM SALARY_HISTORY SH WHERE SH.EMPLOYEE_ID = '00164';
    0 rows selected
    SQL> --
    SQL> -- The value of '00164' in the MANAGER_ID column was set to null
    SQL> -- in the DEPARTMENTS table:
    SQL> --
    SQL> SELECT * FROM DEPARTMENTS D WHERE D.DEPARTMENT_CODE = 'MBMN';
     DEPARTMENT_CODE   DEPARTMENT_NAME                  MANAGER_ID
       BUDGET_PROJECTED   BUDGET_ACTUAL
     MBMN              Board Manufacturing North        NULL
                   NULL            NULL

    1 row selected
    SQL> --
    SQL> ROLLBACK;

    Example 2: Defining a trigger that performs an update

    Before the STATUS_CODE column in WORK_STATUS table is updated,
    the STATUS_CODE_CASCADE_UPDATE trigger in the following SQL
    procedure updates the associated rows in the EMPLOYEES table. The
    REFERENCING clause specifies OLD_WORK_STATUS as the correlation
    name for the values in the WORK_STATUS table before the UPDATE
    statement executes, and NEW_WORK_STATUS as the correlation
    name for the values in the WORK_STATUS table after the UPDATE
    statement executes.

    SQL> -- Display the STATUS_CODE_CASCADE_UPDATE trigger in
    SQL> -- the sample database:
    SQL> --
    SQL> SHOW TRIGGER STATUS_CODE_CASCADE_UPDATE
         STATUS_CODE_CASCADE_UPDATE
     Source:
       STATUS_CODE_CASCADE_UPDATE
                           BEFORE UPDATE OF STATUS_CODE ON WORK_STATUS
                              REFERENCING OLD AS OLD_WORK_STATUS
                                          NEW AS NEW_WORK_STATUS
                           (UPDATE EMPLOYEES E
                            SET E.STATUS_CODE = NEW_WORK_STATUS.STATUS_CODE
                            WHERE E.STATUS_CODE = OLD_WORK_STATUS.STATUS_CODE)
                              FOR EACH ROW
    SQL> --
    SQL> -- Change the STATUS_CODE column with a value of 2 to a value of 3:
    SQL> --
    SQL> UPDATE WORK_STATUS WS SET STATUS_CODE="3" WHERE STATUS_CODE="2";
    1 row updated
    SQL> --
    SQL> -- The trigger changes any STATUS_CODE column in the EMPLOYEES table
    SQL> -- with a value of 2 to a value of 3. Therefore, no rows are
    SQL> -- selected for the first query that follows, but several are selected
    SQL> -- for the second query:
    SQL> --
    SQL> SELECT * FROM EMPLOYEES E WHERE E.STATUS_CODE = "2";
    0 rows selected
    SQL> --
    SQL> SELECT * FROM EMPLOYEES E WHERE E.STATUS_CODE = "3";
     EMPLOYEE_ID   LAST_NAME        FIRST_NAME   MIDDLE_INITIAL
       ADDRESS_DATA_1              ADDRESS_DATA_2         CITY
          STATE   POSTAL_CODE   SEX    BIRTHDAY      STATUS_CODE
     00165         Smith            Terry        D
       120 Tenby Dr.                                      Chocorua
          NH      03817         M      15-May-1954   3

     00178         Goldstone        Neal         NULL
       194 Lyons Av,                                      Colebrook
          NH      03576         M      25-Apr-1952   3

       .
       .
       .
     00358         Lapointe         Jo Ann       C
       70 Tenby Dr.                                       Chocorua
          NH      03817         F      24-Feb-1931   3

    12 rows selected
    SQL> --
    SQL> ROLLBACK;

    Example 3: Defining a trigger that updates a sales summary

    The following example defines a trigger that updates a monthly
    sales total after each daily sale is made.

    SQL> --
    SQL> -- Create the table to keep track of monthly sales:
    SQL> CREATE TABLE MONTHLY_SALES
    cont> ( SALES_AMOUNT INTEGER);
    SQL> --
    SQL> -- Create the table to keep track of sales made today:
    SQL> CREATE TABLE DAILY_SALES
    cont> ( SALES_AMOUNT INTEGER);
    SQL> --
    SQL> -- Assume that $250.00 of sales have been made during the current month:
    SQL> INSERT INTO MONTHLY_SALES
    cont> (SALES_AMOUNT) VALUES (250);
    1 row inserted
    SQL> --
    SQL> -- After adding a new value to the SALES_AMOUNT column in
    SQL> -- DAILY_SALES table, SQL updates the SALES column in
    SQL> -- the MONTHLY_SALES table with the amount of the new sale:
    SQL> CREATE TRIGGER UPDATE_SALES_TOTAL_ON_NEW_SALE
    cont> AFTER INSERT ON DAILY_SALES
    cont>   (UPDATE MONTHLY_SALES M
    cont>       SET M.SALES_AMOUNT = M.SALES_AMOUNT + DAILY_SALES.SALES_AMOUNT)
    cont> FOR EACH ROW;
    SQL> --
    SQL> -- The following statement records a new $5.00 sale for today:
    SQL> INSERT INTO DAILY_SALES
    cont> (SALES_AMOUNT) VALUES (5);
    1 row inserted
    SQL> --
    SQL> -- The value for the SALES_AMOUNT column of the DAILY_SALES table
    SQL> -- is $5.00 and the value of the SALES_AMOUNT column of the
    SQL> -- MONTHLY_SALES table is $255.00:
    SQL> SELECT * FROM DAILY_SALES;
     SALES_AMOUNT
                5
    1 row selected
    SQL> --
    SQL> SELECT * FROM MONTHLY_SALES;
     SALES_AMOUNT
              255
    1 row selected
    SQL> --
    SQL> -- When a new $9.00 sale is made, the values in the two rows of the
    SQL> -- SALES_AMOUNT column of the DAILY_SALES table are $5.00 and $9.00
    SQL> -- and the value of the SALES_AMOUNT column of the MONTHLY_SALES
    SQL> -- table is $264.00:
    SQL> INSERT INTO DAILY_SALES
    cont> (SALES_AMOUNT) VALUES (9);
    1 row inserted
    SQL> --
    SQL> SELECT * FROM DAILY_SALES;
     SALES_AMOUNT
                5
                9
    2 rows selected
    SQL> --
    SQL> SELECT * FROM MONTHLY_SALES;
     SALES_AMOUNT
              264
    1 row selected
    SQL> --
    SQL> ROLLBACK;
    SQL> --

    Example 4: Defining a trigger that sets column values to null

    Before the STATUS_CODE column in the WORK_STATUS table is
    deleted, this trigger causes the associated WORK_STATUS columns
    in the EMPLOYEES table to be set to null.

    SQL> CREATE TRIGGER STATUS_CODE_ON_DELETE_SET_NULL
    cont>  BEFORE DELETE ON WORK_STATUS
    cont>   (UPDATE EMPLOYEES E  SET E.STATUS_CODE = NULL
    cont>    WHERE E.STATUS_CODE = WORK_STATUS.STATUS_CODE)
    cont>  FOR EACH ROW;
    SQL> --
    SQL> -- Delete any row in the WORK_STATUS table where the STATUS_CODE
    SQL> -- column has a value of 1:
    SQL> DELETE FROM WORK_STATUS WS WHERE WS.STATUS_CODE = "1";
    1 row deleted
    SQL> --
    SQL> -- This trigger sets the STATUS_CODE column value to null in many
    SQL> -- rows in the EMPLOYEES table:
    SQL> SELECT * FROM EMPLOYEES E WHERE E.STATUS_CODE IS NULL;
     EMPLOYEE_ID   LAST_NAME        FIRST_NAME   MIDDLE_INITIAL
       ADDRESS_DATA_1              ADDRESS_DATA_2         CITY
          STATE   POSTAL_CODE   SEX    BIRTHDAY      STATUS_CODE
     00416         Ames             Louie        A
       61 Broad st.                NULL                   Alton
          NH      03809         M      13-Apr-1941   NULL

     00374         Andriola         Leslie       Q
       111 Boston Post Rd.         NULL                   Salisbury
          NH      03268         M      19-Mar-1955   NULL
       .
       .
       .

     00200         Ziemke           Al           F
        121 Putnam Hill Rd.         NULL                   Winnisquam
              NH      03289         M      27-Oct-1928   NULL

    88 rows selected
    SQL> ROLLBACK;

    Example 5: Defining a trigger that prevents deletion of a row
    that exists in two tables

    Suppose that a user wants to delete only those rows in the JOB_
    HISTORY table that do not also exist in the JOBS table. This is
    difficult to do with constraints because a row can exist in one
    table with a key number that does not exist in the other table.
    The following statement creates a trigger that causes an error
    when the user tries to delete a row that exists in table JOB_
    HISTORY.

    SQL> CREATE TRIGGER DELETE_GUARD
    cont> BEFORE DELETE ON JOB_HISTORY
    cont> WHEN EXISTS (SELECT JOBS.JOB_CODE FROM JOBS
    cont> WHERE JOBS.JOB_CODE=JOB_HISTORY.JOB_CODE)
    cont> (ERROR) FOR EACH ROW;
    SQL> --
    SQL> -- Now attempt a deletion that violates the trigger.
    SQL> --
    SQL> DELETE FROM JOB_HISTORY WHERE JOB_CODE = 'DMGR';
    %RDB-E-TRIG_INV_UPD, invalid update; encountered error condition
    defined for trigger
    -RDMS-E-TRIG_ERROR, trigger DELETE_GUARD forced an error
    -RDB-F-ON_DB, on database DISK1:[DEPT3.SQL]MF_PERSONNEL.RDB;1

    Example 6: Defining a trigger that saves audit information

    SQL> -- Create new table to record changes made to
    SQL> -- EMPLOYEES table
    SQL> CREATE TABLE AUDIT_TRAIL
    cont> (LOG DATE VMS,
    cont>  PERSON CHAR(31),
    cont> TBL_NAME CHAR(10),
    cont> OPER CHAR(1));
    SQL> COMMIT;

    SQL> -- Create a trigger so that each time
    SQL> -- an INSERT operation is performed,
    SQL> -- a record is stored in the AUDIT_TRAIL table.
    SQL> CREATE TRIGGER EMPS_TRIGGER
    cont> AFTER INSERT
    cont> ON EMPLOYEES
    cont> (INSERT INTO AUDIT_TRAIL
    cont> VALUES (CURRENT_TIMESTAMP,
    cont>         CURRENT_USER, 'EMPLOYEES', 'I'))
    cont> FOR EACH STATEMENT;
    SQL> -- The AUDIT_TRAIL table currently has no records.
    SQL> SELECT * FROM AUDIT_TRAIL;
    0 rows selected
    SQL> -- Insert a record into EMPLOYEES
    SQL> INSERT INTO EMPLOYEES
    cont> (EMPLOYEE_ID, LAST_NAME)
    cont> VALUES ('00964', 'FRENCH');
    1 row inserted
    SQL> -- See if trigger updated the AUDIT_TRAIL table.
    SQL> SELECT * FROM AUDIT_TRAIL;
     LOG                       PERSON                            TBL_NAME     OPER
     17-JUN-2003 15:04:31.43   STEWART                           EMPLOYEES    I
    1 row selected

    Example 7: Using TRACE as a trigger action

    SQL> set flags 'TRACE';
    SQL> create table M_TABLE (a integer, b integer);
    SQL>
    SQL> create trigger T_A
    cont>     after insert on M_TABLE
    cont>     (trace 'in a trigger: ' || cast(M_TABLE.a as varchar(10)))
    cont>     for each row;
    SQL>
    SQL> insert into M_TABLE (a, b) values (1, 10);
    ~Xt: in a trigger: 1
    1 row inserted
    SQL>

    Example 8: Using SIGNAL as a trigger action

    SQL> create table M_TABLE (a integer, b integer);
    SQL>
    SQL> create trigger T_A
    cont>     after insert on M_TABLE2
    cont>     when (M_TABLE2.a is not null)
    cont>         (signal '12345' ('in a trigger: '
    cont>                          || cast(M_TABLE2.a as varchar(10))))
    cont>     for each row;
    SQL>
    SQL> insert into M_TABLE2 (a, b) values (1, 10);
    %RDB-E-SIGNAL_SQLSTATE, routine "T_A" signaled SQLSTATE "12345"
    -RDB-I-TEXT, in a trigger: 1
    SQL>

    Example 9: Using CALL as a trigger action

    SQL> create module M_MODULE
    cont>   language SQL
    cont>
    cont>   procedure M_K (in :a int);
    cont>     trace 'called from a trigger: ' || cast(:a as varchar(10));
    cont>
    cont> end module;
    SQL>
    SQL> create table M_TABLE (a integer, b integer);
    SQL>
    SQL> create trigger T_A
    cont>     after insert on M_TABLE
    cont>     (call M_K (M_TABLE.a))
    cont>     for each row;
    SQL>
    SQL> insert into M_TABLE (a, b) values (1, 10);
    ~Xt: called from a trigger: 1
    1 row inserted
    SQL>
Close Help