数据库生态圈(RDB & NoSQL & Bigdata)——专注于关系库优化(Oracle & Mysql & Postgresql & SQL Server )

https://www.cnblogs.com/lhdz_bj
http://blog.itpub.net/8484829
https://blog.csdn.net/tuning_optmization
https://www.zhihu.com/people/lhdz_bj

导航

DB2开发系列之四——触发器

1、触发器类型

1)BEFORE 触发器:在对表插入或更新之前执行该触发器,允许使用CALL 和 SIGNAL SQL 语句;

2)BEFORE DELETE 触发器:在删除操作之前执行该触发器;

3)AFTER 触发器:在更新、插入或删除操作之后执行。该触发器用于更新反映表间关系和一致性的其他表中的数据,还用于确保数据完整性。AFTER 触发器通常用于在特定情况下向用户生成报警;

4)INSTEAD OF 触发器:该触发器支持对不支持插入、更新和删除操作的视图执行这些操作;

2、创建触发器所需的权限

1)使用触发器的模式ID必须拥有以下权限之一:

      i)对定义 BEFORE 或 AFTER 触发器的表拥有 ALTER 权限;

      ii)对定义 INSTEAD OF 触发器的视图拥有 CONTROL 权限;

      iiI)对定义 INSTEAD OF 触发器的视图拥有所有权;

      iv)对定义触发器的表或视图的模式拥有 ALTERIN 权限;

      v)SYSADM 或 DBADM 授权;

2)以及以下任意一种权限:

      i)IMPLICIT_SCHEMA 数据库授权(如果触发器的隐式或显式模式名称不存在);

      ii)对模式的 CREATEIN 权限(如果触发器的模式名称引用现有的模式);

3)假定授权 ID 没有 SYSADM 和 DBADM 权限并且触发器存在,此 ID 必须拥有以下所有权限:

      i)对定义触发器的表拥有 SELECT 权限 — 用于转换变量和/或表;

      ii)对在触发的操作条件中引用的任意表或视图的 SELECT 权限;

      iii)调用触发的指定 SQL 语句所需的权限;

3、创建触发器语句

1)语法

					
	                          .-NO CASCADE-.
>>-CREATE TRIGGER--trigger-name--+-+------------+--BEFORE-+----->
                                 +-AFTER------------------+
                                 '-INSTEAD OF-------------'

>--+-INSERT--------------------------+--ON--+-table-name-+------>
   +-DELETE--------------------------+      '-view-name--'
   '-UPDATE--+---------------------+-'
             |     .-,-----------. |
             |     V             | |
             '-OF----column-name-+-'

>--+------------------------------------------------------------------+-->
   |              .-------------------------------------------------. |
   |              V  (1)    (2)          .-AS-.                     | |
   '-REFERENCING------------------+-OLD--+----+--correlation-name-+-+-'
                                  |      .-AS-.                   |
                                  +-NEW--+----+--correlation-name-+
                                  |            .-AS-.             |
                                  +-OLD TABLE--+----+--identifier-+
                                  |            .-AS-.             |
                                  '-NEW TABLE--+----+--identifier-'

>--+-FOR EACH ROW--------------+--| triggered-action |--------->
   |  (3)                      |
   '--------FOR EACH STATEMENT-'

triggered-action

|--+-------------------------------------+---------------------->
   |  (4)                                |
   '--------WHEN--(--search-condition--)-'

2)触发器有三个主要组件:

      i)触发器事件;

      ii)触发器条件;

      iii)触发器操作;

3)示例:

      i)简单的 AFTER INSERT 触发器
      CREATE TRIGGER new_emp
      AFTER INSERT ON employee
      REFERENCING NEW AS n
      FOR EACH ROW
      INSERT INTO audit_emp VALUES (n.empno, 'Insert',0.0, current user, current timestamp)

      ii)简单的 AFTER DELETE 触发器
     CREATE TRIGGER purge_emp
     AFTER DELETE ON employee
     REFERENCING OLD AS o
     FOR EACH ROW
     INSERT INTO audit_emp VALUES (o.empno, 'Delete',0.0, current user, current timestamp)
      iii)简单的 AFTER UPDATE 触发器
     CREATE TRIGGER update_emp
     AFTER UPDATE OF salary ON employee
     REFERENCING OLD AS o NEW AS n
     FOR EACH ROW
     WHEN (n.salary <> o.salry)
      INSERT INTO audit_emp VALUES (o.empno,'Update',n.salary,current user, current timestamp)
      iv)简单的 BEFORE UPDATE 触发器
      CREATE TRIGGER update_bemp
      BEFORE UPDATE ON employee
      REFERENCING OLD AS o NEW AS n
      FOR EACH ROW
      WHEN (n.salary = 60000.00)
      SET n.salary = 75000.00)

4、触发器的高级用法

 1)INSTEAD OF 触发器

  --示例

    CREATE TABLE "DB2INST1"."EMPLOYEES"
    (
      "EMPNO"    CHAR(6) NOT NULL     ,
      "FIRSTNME" VARCHAR(12) NOT NULL ,
      "LASTNAME" VARCHAR(15) NOT NULL ,
      "PHONENO"  CHAR(4)              ,
      "SALARY"   DECIMAL(9,2)
      )

    CREATE VIEW employeev AS
    SELECT empno, firstnme, lastname, phoneno
    FROM employees

   CREATE TRIGGER new_emp1
    INSTEAD OF INSERT ON employeev
    REFERENCING NEW AS n
    FOR EACH ROW
    INSERT INTO employees VALUES (n.empno, n.firstnme, n.lastname, n.phoneno, 0)


 2)用触发器处理 XML 数据

  --示例

    CREATE TRIGGER new_order
    BEFORE INSERT ON purchaseorder
    REFERENCING NEW AS N
    FOR EACH ROW
      SET (n.porder) =  xmlvalidate(n.porder
      ACCORDING TOXMLSCHEMA URI 'http://posample.org/order.xsd')
 3)使用 SQL PL 语句扩展触发器主体

      i)语法

					
General Syntax Diagram for CREATE TRIGGER cont.
SQL-procedure-statement

|--+-CALL----------------------------------------------+--------|
   +-Compound SQL (Dynamic)----------------------------+
   +-FOR-----------------------------------------------+
   +-+-----------------------------------+--fullselect-+
   | |       .-,-----------------------. |             |
   | |       V                         | |             |
   | '-WITH----common-table-expression-+-'             |
   +-GET DIAGNOSTICS-----------------------------------+
   +-IF------------------------------------------------+
   +-INSERT--------------------------------------------+
   +-ITERATE-------------------------------------------+
   +-LEAVE---------------------------------------------+
   +-MERGE---------------------------------------------+
   +-searched-delete-----------------------------------+
   +-searched-update-----------------------------------+
   +-SET Variable--------------------------------------+
   +-SIGNAL--------------------------------------------+
   '-WHILE---------------------------------------------'


      ii)从触发器中调用存储过程

      CREATE PROCEDURE write_audit( IN p_empno   CHAR(6),
                              IN p_txt     CHAR(6),
                              IN p_salary  DECIMAL(9,2),
                              IN p_user    CHAR(8),
                              IN p_curtime TIMESTAMP )
      BEGIN
      INSERT INTO audit_emp  VALUES ( p_empno, p_txt, p_salary, p_user, p_curtime )
      END

      CREATE TRIGGER new_emp
      AFTER INSERT ON employee
      REFERENCING NEW AS n
      FOR EACH ROW
      CALL write_audit( n.empno, 'Insert', 0.0, current user, current timestamp)

      iii)使用 SQL PL 的 BEFORE INSERT 触发器

      CREATE TRIGGER business_rules
      BEFORE INSERT ON empprojact
      REFERENCING NEW AS n
      FOR EACH ROW
      BEGIN ATOMIC
      -- Business Rule One (Project ending date Can't be NULL)
      IF (n.emendate IS NULL) THEN
      SET n.emendate = CURRENT date;
      END IF;

      -- Business Rule Two (Project ending date Can't end in last month of the year)
      IF (n.emendate BETWEEN '2009-12-01' AND '2009-12-31') THEN
     SIGNAL SQLSTATE '90000'
        SET MESSAGE_TEXT = 'Business Rule violation - 90000';
      END IF;

     END

 

posted on 2018-03-29 19:10  lhdz_bj  阅读(5034)  评论(0编辑  收藏  举报