SQL可以在CREATE TABLE语句中提供了完整性约束命名子句CONSTRAINT,用于对完整性约束条件命名,从而可以灵活的增加、删除一个完整性约束条件。

完整性约束命名子句

完整性约束命名子句

语法:

  1. CONSTRAINT <完整性约束条件名><完整性约束条件>
  2. -- 完整性约束条件包括NOT NULLUNIQUEPRIMARY KEYFOREIGN KEYCHECK短语等。
-- 建立学生登记表Student,要求学号在90000-999999之间,姓名不能为空,年龄小于30,性别只能是男或女
CREATE TABLE Student(
Sno NUMERIC(6)
    CONSTRAINT C1 CHECK (Sno BETWEEN 90000 and 99999),
SNAME CHAR(20)
    CONSTRAINT C2 NOT NULL,
SAGE NUMERIC(3)
    CONSTRAINT C3 CHECK(SAGE < 30),
SSEX CHAR(2) 
    CONSTRAINT C4 CHECK (SSEX IN('男','女')),
    CONSTRAINT STUDENTKEY PRIMARY KEY(SNO)
);

修改表中的完整性限制

-- 删除约束性条件
ALTER TABLE Student 
    DROP CONSTRAINT C4;
-- 增加约束性条件
AlTER TABLE Student
    ADD CONSTRAINT C1 CHECK (SNO BETWEEN 9000 AND 9999);

断言

在SQL中可以使用数据定义语言中的CREATE ASSERTION语句,通过声明性断言来指定更具一般性的约束

创建断言的语句格式

CREATE ASSERTION <断言名><CHECK 子句>
-- 限制数据库课程最多60名学生选修
CREATE ASSERTION ASSE_SC_DB_NUM 
CHECK (60>=(SELECT COUNT(*) FROM COURSE,SC WHERE SC.CNO=COURSE.CNO AND COURSE.CNAME='数据库'))
-- 每次SC表中添加一条元组,这个断言机制都会被触发一遍

删除断言的语句格式

DROP ASSERTION <断言名>

触发器

触发器是用户定义在关系表上的一类有事件驱动的特殊过程。触发器类似于约束,但是比约束更加灵活,可以实施更为复杂的检查和操作,具有更精细和更强大的数据控制能力。

定义触发器

触发器又叫做事件-条件-动作规则。

CREATE TRIGGER <触发器名>             /*每当触发事件发生时,该触发器被激活*/
{BEFORE | AFTER}<触发事件> ON <表名>   /*指明触发器激活的时间是在执行触发事件前或后*/
REFERENCING NEW|OLD ROW AS<变量>      /*REFERENCING指出引用的变量*/
FOR EACH{ROW|STATEMENT}              /*定义触发器的类型,指明动作执行的频率*/
[WHEN <触发条件>] <触发动作者>          /*仅当触发条件为真时才执行触发动作体*/

部分语义说明:

  • 只有表的拥有者,即创建表的用户才可以在表上创建触发器

  • 触发器名:可以包括模式名,也可以不包括模式名。同一模式下、触发器名必须是唯一的,并且触发器名和表名必须在同一模式下

  • 触发器只能定义在基本表上

  • 触发事件:可以是INSERT、DELETE或UPDATE,也可以是这几个事件的组合。AFTER/BEFORE是触发时机

  • 触发器类型:按照触发动作的间隔尺寸可以分为行级触发器(FOR EACH ROW)和语句触发器(FOR EACH STATEMENT)

  • 触发条件:只有触发条件为真时,才会触发

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

create trigger SC_T                 /*SC_T是触发器的名字*/
    after update of Grade ON SC     /*UPDATE OF Grade ON SC 是触发事件,
                                      After是触发的时机,表示对SC的Grade属性修改完后再触发下面的规则*/
    referencing
    OLDROW as OldTuple,
    NEWROW as NewTuple
FOR EACH ROW                        /*行级触发器,即每执行一次Grade的更新,下面的规则就执行一次*/
WHEN (NewTuple.Grade>=1.1*OldTuple) /*触发条件,只有该条件为真时才执行*/
    INSERT INTO SC_U(Sno, Cno, OldGrade, NewGrade)  /*下面的insert操作*/
    values (OldTuple.Sno, OldTuple.Cno, OldTuple.Grade, NewTuple.Grade);

激活触发器

触发器的执行是有触发事件激活的,并由数据库服务器自动执行的。

触发器激活时遵循如下的执行顺序:

  1. 激活该表的BEFORE触发器

  2. 激活触发器的SQL语句

  3. 执行该表上的AFTER触发器

对于同一个表上的多个BEFORE(AFTER)触发器1,遵循“谁先创建谁先执行”的原则,即按照触发器创建的时间先后顺序执行。有些关系数据库管理系统是按照触发器名字的字母排序顺序执行触发器的。

删除触发器

DROP TRIGGER<触发器名> ON <表名>

触发器是一种功能强大的工具,但在使用时要慎重,因为每次访问一个表时都可能触发一个触发器,这样会影响系统的性能。