• 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

  • 相关阅读:
    MySQLday04(剩余窗口函数,其他常用函数,存储引擎,如何选择数据类型,字符集,索引,存储过程,触发器,LOCK TABLES 和 UNLOCK TABLES,事务控制,分布式事务的使用,JDBC)
    MySQLday03(JSON类型,算术运算符,比较运算符,逻辑运算符,位运算符,运算符的优先级,字符串函数,数值函数,日期和时间函数,流程函数,JSON函数,窗口函数)
    Mysqlday02(导入外部sql文件,order by,group by,having,多表联查,查元数据,数值类型,日期类型,字符数据类型)
    Mysqlday01(Mysql简介,sql简介,分类)
    Spring Boot 入门实战(6)--JdbcTempalte、Mybatis 、多数据源及 Atomicos 整合(XA 事务)
    Spring Boot 入门实战(5)--JdbcTempalte、Mybatis及多数据源整合(单库事务)
    Java 操作 XML(11)--XMLBeans 使用
    Qt QThread 创建多线程程序
    C++Primer第五版 第十三章 拷贝控制
    QtCreator float与QString之间的转化
  • 原文地址:https://www.cnblogs.com/lhdz_bj/p/8671793.html
Copyright © 2020-2023  润新知