关系性数据库的完整性是指数据的正确性和相容性,主要是为了防止数据库中存在不符合语意的数据。在关系型数据库中的完整性规则是对关系的某种约束条件,这些约束条件实际上就是现实世界的一些基本的要求。在关系模型中有三种完整性约束:实体完整性,参照完整性和用户定义的完整性。其中前面两个:实体完整性和参照完整性是关系模型的必备两个约束条件,即所谓两个不变性。用户定义完整性则是针对某一具体关系数据库的约束条件,它要求某一关系必须要求所包含数据必须满足某种语意的要求。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
在用户定义完整性上,触发器(Trigger)是一种经常被使用的方法。微软的SQL Server作为一种关系型数据库,对于触发器也有比较全面的功能支持。触发器是一种特殊类型的存储过程,他的主要作用就是其能够实现主键和外键不能保证的复杂的参照完整性,同时Trigger还可以强化约束,跟踪变化,级联运行和存储过程的调用。在Trigger的类型上SQL Server支持两种类型的触发器:AFTER和INSTEDOF。在Trigger的实现方法上SQL Server支持触发器的递归和嵌套。这里我们主要对Trigger的嵌套和递归做实验测试。
一.SQL Server的嵌套和递归
SQL Server可以对使用recursive triggers,
nested triggers
分别对Trigger的递归和嵌套做设置, 根据微软的相关资料:
RECURSIVE_TRIGGERS:只能限制直接递归,不能限制间接递归。
Nested_triggers : 允许的嵌套层数最多是32层。
我们这里主要实验以下几个问题:
1.
RECURSIVE_TRIGGERS和nested_triggers的的设置方法。
2.
RECURSIVE_TRIGGERS和nested_triggers的对于Trigger的影响。
3.
Trigger的编写方法和Trigger的实际效果。
二.SQL Server的嵌套和递归的实现
1.
RECURSIVE_TRIGGERS 的设置:
其指令如下:
ALTER DATABASE ‘Emp_Struct’ SET RECURSIVE_TRIGGERS OFF(ON);
Recursive triggers: ON: 设置递归开启 ;OFF: 设置递归为关闭
2.
Nested triggers 的设置:
其指令如下:
EXEC sp_configure 'nested_triggers', 1(0)
RECONFIGURE WITH OVERRIDE
Nested triggers: 1 : 设置嵌套开启 ;0 : 设置嵌套关闭
3.
测试数据库及表格
3.1建立一个测试数据库:Emp_Struct,
其中包含三个表格: employee, manager, Department
其结构说明如下:
Employee:
欗位
|
Emp_id
|
Emp_name
|
Depart
|
Manager
|
Duty
|
Report_num
|
属性
|
int
|
Char(20)
|
Char(20)
|
Char(20)
|
Char(20)
|
int
|
说明
|
员工号
|
姓名
|
部门
|
管理人
|
职位
|
下属人员数
|
manager
欗位
|
Manager_name
|
Sec_manager
|
depart
|
Under_num
|
属性
|
Char(20)
|
Char(20)
|
Char(20)
|
int
|
说明
|
主管理人
|
从管理人
|
部门
|
下属人员数
|
Department:
欗位
|
Depart_name
|
Manager_name
|
Member_num
|
属性
|
Char(20)
|
Char(20)
|
int
|
说明
|
部门
|
管理人
|
人员总数
|
3.2建立触发器:
为了实现触发器嵌套,我们共设置4个触发器,
Insert_manager(employee),
Del_manager(employee),
upmanager(manager),
up_depart(depart)
其触发器嵌套顺序如下:
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
Update
employee
|
employee
|
Update Manager
|
manager
|
department
|
Update department
|
Update employee
|
up_manager
|
up_depart
|
Insert_manager
(Del_manager)
|
User Delete (insert) employee
|
If Delete(insert) manager
|
up_employee
|
Update employee
|
3.3建立完数据库和表格以后,插入部分测试数据如下图:
3.4将递归和嵌套参数都设置为打开状态
3.4 插入一个名为TREE职位(duty)为manager的数据:
在employee表上产生递归操作到最大嵌套层32层。数据插入未成功。
3.5
将递归选项关闭,保留嵌套。执行数据插入:
三个表格的数据被更新。新manager TREE的资料被插入,原Manager HONG被标记为sec_manager ,部门人数更新为7人,报告人数更新为6人。
3.6
将递归选项关闭,保留嵌套。删除TREE的相关信息。
同时正常出发嵌套的出发器,同时删除数据成功。
3.7
设置递归和嵌套的参数都设置为OFF,重新插入名字为TREE的资料
重新插入TREE的资料,数据插入employee但只触发了第一层的insert_manager触发器,
故插入的数据未能更新所有相关表格
3.8设置递归为ON和嵌套为OFF,重新插入TREE数据
为产生递归,仅触发了第一个触发器。
以上结果汇总如下:
设置
|
Recursive OFF
|
Recursive ON
|
Nest OFF
|
不可产生递归
不可触发嵌套
|
不可产生递归
不可触发嵌套
|
Nest ON
|
不产生递归
可触发嵌套
|
可产生递归
可触发嵌套
|
验证并得出以下结果:
1.
递归和嵌套必须同时设置,递归有效才可用。
2.
递归设置只能限制直接递归,不能限制间接递归。
3.
嵌套的最大层数是32层
4.
无法设置嵌套层数,但在应用中可以通过@@nestlevel判断嵌套的层数,讓后决定是否执行此Trigger这样就可以控制trigger的嵌套层数。
转载于:https://blog.51cto.com/parker/37769