首页 > 数据库 >(数据库系统概论|王珊)第五章数据库完整性-第四、六、七节:约束命名子句、断言和触发器

(数据库系统概论|王珊)第五章数据库完整性-第四、六、七节:约束命名子句、断言和触发器

时间:2023-02-19 13:01:02浏览次数:54  
标签:触发 触发器 王珊 CONSTRAINT 七节 CREATE SQL Student 子句

(数据库系统概论|王珊)第五章数据库完整性-第四、六、七节:约束命名子句、断言和触发器_触发器

一:完整性约束命名子句(CONSTRAINT)

SQL中还提供了完整性约束命名子句​​CONSTRAINT​​用来对完整性约束条件进行命名,从而可以灵活地增加、删除一个完整性约束条件

(1)完整性约束命名子句

语法

(数据库系统概论|王珊)第五章数据库完整性-第四、六、七节:约束命名子句、断言和触发器_完整性约束_02

演示

例如, 建立学生登记表​​Student​​,要求学号在90000~99999之间,姓名不能取空值,年龄小于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)
);
  • 因此在​​Student​​表上建立了StudentKey、C1、C2、C3、C4这5个约束条件

例如,建立教师表​​Teacher​​​,要求每个教师的应发工资不低于3000元。应发工资是工资列​​Sal​​​与扣除项​​Deduct​​之和

CREATE TABLE Teahcer
(
Tno NUMERIC(4) PRIMARY KEY,
TName CHAR(10),
TSal NUMERIC(7,2),
TDeduct NUMERIC(7,2),
TDeptno NUMERIC(2),

CONSTRAINT TeacherKey FOREIGN KEY(Tdeptno) REFERENCES DEPT(TDeptno),
CONSTRAINT C1 CHECK(TSal+TDeduct >= 3000)
);
  • 因此在​​Teacher​​表上建立了TeacherKey、C1这2个约束条件

(2)修改表中的完整性限制

语法:这一点,我们在​​(数据库系统概论|王珊)第三章关系数据库标准语言SQL-第二、三节:数据定义​​这一节中讲到过

(数据库系统概论|王珊)第五章数据库完整性-第四、六、七节:约束命名子句、断言和触发器_SQL_03

  • ADD:用于增加新列,新的列级完整性约束条件和新的表级完整性约束条件
  • DROP COLUMN:用于删除表中的列
  • DROP CONSTRAINT:用于删除指定的完整性约束条件
  • ALTER COLUMN:用于修改原有的列定义

演示

例如,去除​​Student​​表中对性别的限制

ALTER TABLE Student
DROP CONSTRAINT C4;

例如, 修改​​Student​​表中的约束条件,要求学号改为在0~100之间,年龄由小于30改为小于40

  • 策略就是先删除再增加
ALTER TABLE Student DROP CONSTRAINT C1;
ALTER TABLE Student ADD CONSTRAINT C1 CHECK(Sno BETWEEN 0 AND 100);
ALTER TABLE Student DROP CONSTRAINT C3;
ALTER TABLE Student ADD CONSTRAINT C3 CHECK(Sage < 40);

二:断言(ASSERTION)

  • 在高级语言,例如C++、JAVA中就在经常使用断言​​assert​​,所以它的作用大家应该比较熟悉

在SQL中通过声明性断言可以指定更具一般性的约束(例如涉及多表、聚集操作等)。创建断言后,任何对断言中所涉及关系的操作都会触发DBMS对断言的检查,任何断言为FALSE的操作都会被拒绝

(1)创建断言

语法:在SQL中,使用CREATE ASSERTION语句来创建断言,格式如下

(数据库系统概论|王珊)第五章数据库完整性-第四、六、七节:约束命名子句、断言和触发器_完整性约束_04

演示

例如,限制数据库课程最多60名学生选修

CREATE ASSERTION ASS_SC_DB_NUM  CHECK
(
60 >=
(
SELECT count(*)
FROM Cource,sc
WHERE sc.Cno=Course.Cno AND Course.Cname='数据库'
)
);

例如,限制每一门课程最多60名学生选修

CREATE ASSERTION ASS_SC_CNUM CHECK
(
60 >=
ALL
(
SELECT count(*)
FROM SC
GROUP BY Cno
)
);

(2)删除断言

语法

(数据库系统概论|王珊)第五章数据库完整性-第四、六、七节:约束命名子句、断言和触发器_完整性约束_05

三:触发器(TRIGGER)

触发器(TRIGGER):是用户定义在关系表上的一类由事件驱动的特殊过程,在满足一定条件或达到一定阈值时会自动触发。可以进行更为复杂的检查和操作,具有更精细和更强大的数据控制能力

(1)定义触发器

触发器又叫做事件-条件-动作(event- condition-action)规则。当特定的系统事件(如对一个表的增、删、改操作,事务的结束等)发生时,对规则的条件进行检查,如果条件成立则执行规则中的动作,否则不执行该动作。规则中的动作体可以很复杂,可以涉及其他表和其他数据库对象,通常是一段SQL存储过程

  • 就如同古老的VB语言就是一种以事件驱动为机制的语言,例如一些控件的​​CLICK​​(点击)事件等等

语法:SQL使用CREATE TRIGGER语句定义触发器,其格式如下

  • 只有表的创建者才可以在表上创建触发器,并且一个表上只能创建有限数量的触发器

(数据库系统概论|王珊)第五章数据库完整性-第四、六、七节:约束命名子句、断言和触发器_SQL_06

  • 触发器名:可以包含模式名,也可以不包含;同一模式下,触发器名必须是唯一的,并且触发器名和表名必须在同一模式下
  • 表名触发器只能定义在表上,不可在视图上。当基本表的数据发生变化时,将激活定义在该表上相应触发事件的触发器
  • 触发事件可以是INSERT、DELETE或UPDATE,也可以是它们的组合;同样也可以​​UPDATE OF<列名,...,>​​​,也即进一步指明哪些列变化时需要激活触发器;**​​AFTER/BEFORE​​**是触发时机
  • 触发器类型触发器按照所触发动作的间隔尺寸可以分为行级触发器(FOR EACH ROW)和语句级触发器(​FOR EACH STATEMENT​;语句级会执行一次,行级执行的次数以表的具体行数而定
  • 触发条件:触发器被激活时,只有当触发条件为真时触发动作体才执行,否则触发动作体不执行;如果省略WHEN触发条件,则触发动作体在触发器激活后立即执行
  • 触发动作体触发动作体既可以是一个匿名PL/SQL 过程块,也可以是对已创建存储过程的调用。如果是行级触发器,用户可以在过程体中使用​​NEW​​​和​​OLD​​​引用​​UPDATE/INSERT​​​事件之后的新值和​​UPDATE/DELETE​​事件之前的旧值;如果是语句级触发器,则不能在触发动作体中使用​​NEW​​​或​​OLD​​进行引用。如果触发动作体执行失败,激活触发器的事件(即对数据库的增、删、改操作)就会终止执行,触发器的目标表或触发器可能影响的其他对象不发生任何变化

演示

【例如】当对​​SC​​​表的​​Grade​​属性进行修改时,若分数增加了10%,则将此次操作 记录到另一个表​​SC_ U (Sno、Cno、 Oldgrade、 Newgrade)​​​ 中,其中​​Oldgrade​​​是修改前的分数,​​Newgrade​​ 是修改后的分数

CREATE TRIGGER SC_T //触发器名字
AFTER OF Grade ON SC //在对sc表的Grade更新后再触发

REFERENCING
OLDROW AS OldTuple
NEWROW AS NewTuple
FOR EACH ROW //行级触发器,也即每更新一次,下面规则就会执行一次
WHEN (NewTuple.Grade >= 1.1*OldTuple.Grade) //触发条件为真才会执行
INSERT INTO SC_U (Sno,Cno,OldGrade,NewGrade)
VALUES(OldTuple.Sno,OldTuple.Cno,OldTuple.Grade,NewTuple.Grade)
  • 在本例中​​REFERENCING​​指出引用的变量
  • 如果触发事件是​​UPDATE​​​操作并且有​​FOR EACH ROW​​​子句,则可以引用的变量有​​OLDROW​​​和​​NEWROW​​,分别表示修改之前的元组和修改之后的元组
  • 若没有​​FOR EACH ROW​​​子句,则可以引用的变量有​​OLDTABLE​​​和​​NEW TABLE​​​, ​​OLDTABLE​​表示表中原来的内容,​​NEWTABLE​​表示表中变化后的部分

【例如】将每次对​​Student​​表的 插入操作所增加的学生个数 记录到​​StudentInsertLog​​中

CREATE TRIGGER Student_Count
AFTER INSERT ON Student
REFERENCING
NEWTABLE AS DELTA

FOR EACH STATEMENT //语句级
INSERT INTO StudentInsertLog(Numbers)
SELECT COUNT(*) FROM DELTA
  • ​DELTA​​​是一个关系名,其模式与​​Student​​​相同,包含的元组是​​INSERT​​语句增加的元组

【例如】定义一个​​BEFORE​​​行级触发器,为教师表​​Teacher​​定义完整性规则“教授的工资不得低于4000元,如果低于4000元,自动改为4000元

CREATE TRIGGER Insert_Or_Update_Sal
BEFORE INSERT OR UPDATE ON Teacher
REFERENCING NEWROW AS NewTuple
FOR EACH ROW
BEGIN //这是一个PL/SQL过程快
IF(NewTouple.Job='教授') AND (NewTouple.Sal < 4000)
THEN NewTouple.Sal:=4000;
END IF
END;

(2)激活触发器

触发器的执行是由触发器事件激活的,如果同一个表上有多个触发器,激活时会按照以下顺序执行

1. 执行该表上的BEFORE触发器 2. 激活触发器的SQL语句 3. 执行该表上的​AFTER​触发器

对于同一个表上的多个​​BEFORE(AFTER)​​触发器,遵循“谁先创建谁先执行”的原则,即按照触发器创建的时间先后顺序执行

(3)删除触发器

语法:

(数据库系统概论|王珊)第五章数据库完整性-第四、六、七节:约束命名子句、断言和触发器_SQL_07

标签:触发,触发器,王珊,CONSTRAINT,七节,CREATE,SQL,Student,子句
From: https://blog.51cto.com/u_14913756/6066703

相关文章