数据库 - 触发器与域中的完整性限制

域中的完整性限制

SQL支持域的概念,并可以用CREATE DOMAIN语句建立一个域以及该域应该满足的完整性约束条件。
[例14]建立一个性别域,并声明性别域的取值范围
           CREATE DOMAIN GenderDomain CHAR(2)
           CHECK (VALUE IN (‘男‘‘女‘) );
          这样[例10]中对Ssex的说明可以改写为
          Ssex GenderDomain
[例15]建立一个性别域GenderDomain,并对其中的限制命名
           CREATE DOMAIN GenderDomain CHAR(2)
           CONSTRAINT GD CHECK ( VALUE IN (‘男‘‘女‘) );
[例16]删除域GenderDomain的限制条件GD。
           ALTER  DOMAIN  GenderDomain  
           DROP CONSTRAINT GD;
[例17]在域GenderDomain上增加限制条件GDD。
          ALTER  DOMAIN  GenderDomain  
         ADD CONSTRAINT GDD CHECK (VALUE IN ( ‘1‘‘0‘) ); 
通过[例16]和[例17],就把性别的取值范围由(‘男‘,‘女‘)改为 ( ‘1‘,‘0‘) 

触发器(Trigger)

触发器(Trigger)是用户定义在关系表上的一类由事件驱动的特殊过程
由服务器自动激活
可以进行更为复杂的检查和操作,具有更精细和更强大的数据控制能力

定义触发器

CREATE TRIGGER语法格式

      CREATE TRIGGER <触发器名>  
       {BEFORE | AFTER} <触发事件> ON <表名>
        FOR EACH  {ROW | STATEMENT}
      [WHEN <触发条件>]
        <触发动作体>

定义触发器的语法说明:
1. 创建者:表的拥有者
2. 触发器名
3. 表名:触发器的目标表
4. 触发事件:INSERT、DELETE、UPDATE
5. 触发器类型
行级触发器(FOR EACH ROW)
语句级触发器(FOR EACH STATEMENT)

例如,假设在[例11]的TEACHER表上创建了一个AFTER UPDATE触发器。如果表TEACHER有1000行,执行如下语句:
    UPDATE TEACHER SET Deptno=5; 
如果该触发器为语句级触发器,那么执行完该语句后,触发动作只发生一次
如果是行级触发器,触发动作将执行1000次 
  1. 触发条件
    触发条件为真
    省略WHEN触发条件

  2. 触发动作体
    触发动作体可以是一个匿名PL/SQL过程块
    也可以是对已创建存储过程的调用

[例18]  定义一个BEFORE行级触发器,为教师表Teacher定义完整性规则“教授的工资不得低于4000元,如果低于4000元,自动改为4000元”。
    CREATE TRIGGER Insert_Or_Update_Sal 
         BEFORE INSERT OR UPDATE ON Teacher  
        /*触发事件是插入或更新操作*/
         FOR EACH ROW                      /*行级触发器*/
        AS BEGIN                                  /*定义触发动作体,是PL/SQL过程块*/
              IF (new.Job=‘教授‘) AND (new.Sal < 4000) THEN   
              new.Sal :=4000;                
              END IF;
        END;                               
[例19]定义AFTER行级触发器,当教师表Teacher的工资发生变化后就自动在工资变化表Sal_log中增加一条相应记录
   首先建立工资变化表Sal_log
    CREATE TABLE Sal_log
        (Eno    NUMERIC(4)  references teacher(eno),
          Sal     NUMERIC(72),
          Username  char(10),
          Date   TIMESTAMP
         );
[例19](续)
CREATE TRIGGER Insert_Sal                   
    AFTER INSERT ON Teacher         /*触发事件是INSERT*/
    FOR EACH ROW
    AS BEGIN
        INSERT INTO Sal_log VALUES(
           new.Eno,new.Sal,CURRENT_USERCURRENT_TIMESTAMP);
    END;
[例19](续)
CREATE TRIGGER Update_Sal               
   AFTER UPDATE ON Teacher      /*触发事件是UPDATE */
   FOR EACH ROW
   AS BEGIN 
     IF (new.Sal <> old.Sal) THEN INSERT INTO Sal_log VALUES(
          new.Eno,new.Sal,CURRENT_USERCURRENT_TIMESTAMP);
     END IF;
  END;

激活触发器

触发器的执行,是由触发事件激活的,并由数据库服务器自动执行
一个数据表上可能定义了多个触发器
同一个表上的多个触发器激活时遵循如下的执行顺序:
(1) 执行该表上的BEFORE触发器;
(2) 激活触发器的SQL语句;
(3) 执行该表上的AFTER触发器。

[例20]执行修改某个教师工资的SQL语句,激活上述定义的触发器。
     UPDATE Teacher SET Sal=800 WHERE Ename=‘陈平‘;
    执行顺序是:
执行触发器Insert_Or_Update_Sal
执行SQL语句“UPDATE Teacher SET Sal=800 WHERE Ename=‘陈平‘;”
执行触发器Insert_Sal;
执行触发器Update_Sal 

删除触发器

删除触发器的SQL语法:
DROP TRIGGER <触发器名> ON <表名>;
触发器必须是一个已经创建的触发器,并且只能由具有相应权限的用户删除。

[例21]  删除教师表Teacher上的触发器Insert_Sal
     DROP TRIGGER Insert_Sal ON Teacher;

数据库的完整性是为了保证数据库中存储的数据是正确的

RDBMS完整性实现的机制
完整性约束定义机制
完整性检查机制
违背完整性约束条件时RDBMS应采取的动作

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。