数据库复习九

# 完整性概述

什么是数据库的完整性

  • 数据的正确性和相容性
  • 防止不合语义的数据进入数据库

完整性控制机制

  • 完整性约束条件定义机制

    完整性约束条件:数据模型的组成部分约束数据库中数据的定义

    DBMS 应提供定义数据库完整性约束条件,并把它们作为模式的一部分存入数据库中

  • 完整性检查机制

    由 DBMS 提供的检查用户发出的操作请求是否违背了完整性约束条件的功能

  • 违约反应

    如果发现用户的操作请求使数据违背了完整性约束条件,则采取一定的动作来保证数据的完整性

# 完整性约束条件

完整性约束条件对象:

  • 列:对属性的取值类型、范围、精读等约束条件
  • 元组:对元组中各个属性列间的联系的约束
  • 关系:对若干元组间、关系集合上以及关系之间联系的约束

SQL-DDL 中关于完整性的命令:

  • Col_constr 列约束:一种域约束类型,对单一列值进行约束,只能应用在单一列上

    {NOT NULL| #列值非空
    	[CONSTRAINT constraintname] #为约束命名,使用以后撤销
    	{ UNIQUE #列值是唯一的
    	  | PRIMARY KEY #列为主键
    	  | CHECK (search_cond) #列值满足条件,条件只能使用列当前值
    	  | REFERENCES tablename [ (colname)] [ON DELETE CASCADE]
    	  # 引用另一表 tablename 约束 colname 的值,如有 ON DELETE CASCADE 语句,则删除被引用表的某列值 v 列,要将本表的该列值为 v 的列值更新为 null,缺省值为误操作
    	}
    }
  • table_constr 表约束:一种关系约束类型,对多列或元组的值进行约束,是应用在关系上,即对关系的多列或元组进行约束,列约束是其特例

    [CONSTRAINT constraintname] #为约束命名,使用以后撤销
    	{ UNIQUE (colname {,colname...}) #列值组合在一起是唯一的
    	  | PRIMARY KEY (colname,{,colname...})#列为主键
    	  | CHECK (search_condition) #元组多列满足条件,条件只能使用同一元组的不同列当前值
    	  | FOREIGN KEY (colname,{,cloname,...}) REFERENCES tablename [(colname{,colname...})] [ON DELETE CASCADE] #引用另一表 tablename 的若干列的值作为外键

# 触发器技术

SQL-DDL 提供另一种完整性保证机制是触发器 Trigger

Create Table 中的表约束和列约束基本上就是静态的约束,也基本上都是对单一列或单一元组的约束 (尽管有参照完整性约束),为实现动态约束以及多个元组之间的完整性约束,就需要触发器 Trigger

Trigger 是一种过程性完整性约束 (相比之下,Create Table 中定义的都是非过程性约束),是一段程序,该程序可以在特定的时刻使被自动触发执行,比如在一次更新操作之前执行,或在更新操作之后执行。

触发器 Trigger

CREATE TRIGGER trigger_name BEFORE|AFTER
	{INSERT|DELETE|UPDATE [OF colname {,colname...}]}
	ON tablename [REFERENCES corr_Name_def {,corr_name_def...}]
	[FOR EACH ROW | FOR EACH STATEMENT] #对更新操作的每一条结果 (前者),或整个更新操作完成 (后者)
	[WHEN (search_condition)] #检查条件,如满足执行下述程序
		{statement #单行程序直接书写,多行程序要用下行方式
		|BEGIN ATOMIC statement; {statement;...}END}

触发器 Trigger 的意义:

当某一事件发生时 (Before|After),对该事件产生的结果 (或是每一元组,或是整个操作的所有元组),检查条件 search_condition,如果满足条件,则执行后面的程序段,条件或程序段中引用的变量可用 corr_name_def 来限定

例:设计一个触发器,当进行 Teacher 表更新元组时,使其工资只能升不能降

CREATE trigger teacher_chgsal before update of salary
	on teacher
	referencing new x,old y
	for each row when (x.salary<y.salary)
		begin
			raise application_error(-20003,'invalid salary on update'); #此条件为 Oracle 的错误处理函数
        end;

假设 Student (Sno,Sname,SumCourse),SumCourse 为该同学已学习课程的门数,初始值为 0,以后每选修一门都要对其增 1,设计一个触发器完成上述功能

CREATE trigger sumc after insert on sc
	referencing new row newl
	for each row
		begin
			update student set SumCourse = SumCourse +1
			where Sno=newi.Sno;
		end;

# 一、SQL SERVER 创建触发器

基本语句如下:

create trigger trigger_name
on {table_name|view_name}
{for|After|Instead of}
[insert,update,delete]
as
sql_statement

# 二、SQL 触发器简介

触发器是一种特殊的存储过程,它不能被显式地调用,而是在表中插入记录,更新记录或者删除记录时被自动地激活

SQL Server 为每个触发器都创建了两个专用表:Inserted 表和 Deleted 表

Deleted 表存放由执行 Delete 或 Update 语句而要从表中删除的所有行

Inserted 表存放由于执行 Insert 或 Update 语句而要向表中插入的所有行

1、插入操作:Inserted 表有数据,Deleted 表无数据

2、删除操作:Inserted 表无数据,Deleted 表有数据

3、更新操作:Inserted 表有数据,Deleted 表有数据

例子:

CREATE TRIGGER deleteOrUpdateTrigger
ON Student
after Delete,Update,Insert
AS if exists(select * from inserted)
	if exists(select * from deleted)
		print '...更新'
	else
		print '... 插入'
   else
   	if exists(select * from deleted)
   		print '...删除'