DML触发器实现数据完整性的应用研究

2015-01-06 18:50孔丽云
电脑知识与技术 2014年34期

孔丽云

摘要:数据完整性是确保数据库数据安全的重要研究内容。通过DML触发器技术实现数据完整性控制,可有效防止由于对数据进行频繁的更新操作从而导致数据丢失或无效扩散。该文通过论述DML触发器的实现机制,并结合具体的开发实例,分析DML触发器在强制数据参照完整性、级联更新与删除、实现用户定义业务规则、更新不可更新视图等方面的应用基本步骤及设计技巧,反映了触发器应用在提高系统性能、简化数据库操作、维护数据完整性、有效性、增强数据库安全性、提高开发效率等方面的强大功能。

关键词:数据库;DML触发器;数据完整性;T-SQL

中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2014)34-8087-04

数据完整性(Data Integrity)是数据安全的三个基本要点之一[1],是数据库应用系统开发的重要内容。它是指数据的精确性(Accuracy) 和可靠性(Reliability),是应防止数据库中存在不符合语义规定的数据和防止因错误信息的输入输出造成无效操作或错误信息而提出的。数据完整性分为四类:实体完整性(Entity Integrity)、域完整性(Domain Integrity)、参照完整性(Referential Integrity)、用户定义完整性(User-definedIntegrity)。其中域完整性,实体完整性和参照完整性,是关系模型必须满足的完整性约束条件[2]。对数据库的完整性控制和安全性控制均属于DBMS提供的数据保护机制。完整性控制主要包含完整性约束、并发控制、故障恢复三种,其中完整性约束是完整性控制的核心。完整性约束可以通过DBMS或应用程序来实现,基于DBMS的完整性约束作为模式的一部分存入数据库中,通过DBMS实现的数据完整性按照数据库设计步骤进行设计,而由应用软件实现的数据库完整性则纳入应用软件设计[3]。DBMS级的数据完整性相当于语法级的数据完整性,而要完成语义级数据完整性,除了需建立在语法级数据完整性的基础上,还应完成在应用系统层次上的完整性和一致性处理逻辑,在这些逻辑执行期间利用语法级的数据完整性来最终实现对应用系统可用和有效的应用级数据完整性。

DBMS级数据完整性实现机制包括数据类型、规则、默认值、约束、触发器和XML架构[4]。DBMS级数据完整性除了可有效防止不符合语义规定的数据,也可用于定义与实现业务逻辑规则。由于集中定义更利于降低应用程序的复杂性及提高应用程序的运行效率。但当实施相对复杂的数据完整性时,使用触发器相对更为灵活。

1 触发器的概述

触发器(Trigger)是用户定义在关系表上的一类由事件驱动的特殊存储过程。一般存储过程是通过调用过程名及提供所需对应参数而被执行。触发器不能被显式调用,而是通过对它所绑定的数据表执行相关事件激活触发器而被执行的。SQL Server 2012 实现了三种类型的触发器: 数据操纵语言(DML,Data Manipulation Language)触发器,在向表中插入、更新或删除数据等事件发生时被触发;数据定义语言触发器(DDL,Data Definition Language),在创建、修改或删除数据库对象时触发;登录触发器,在登录的身份验证阶段完成之后且用户会话实际建立之前为响应 LOGON 事件而触发[5]。

2 DML触发器的分类

在触发器中,应用最为广泛当属DML触发器。DML 触发器可用于强制业务规则和数据完整性、查询其他表并包括复杂的 Transact-SQL 语句。

DML的触发事件包括 INSERT、UPDATE 或 DELETE语句。 DML触发器一旦被定义,任何用户对表或视图的Insert、Update和Delete操作均由服务器自动激活相应的触发器,在DBMS核心层进行集中的完整性控制[6]。DML触发器可分为After 触发器、Instead of 触发器、CLR触发器。

After触发器是指导致触发器被触发的事件被成功执行后(如果是在存储过程,而且有事务,则要在事务提交之后),触发器才会被激活执行,若激活操作违反约束或发生错误,则激活操作会被拒绝或回滚,触发器不被触发;而Instead of 触发器是指激活触发器的操作(Insert、Update、Delete)被触发器中所定义的操作替代,激活触发器的语句并不被实际执行,但数据更改的变动仍可反映到Inserted和Deleted两张临时表中;CLR触发器将执行托管代码中编写的方法,而不用执行T-SQL存储过程。

3 DML触发器与约束

实体完整性(Entity Integrity)通常可通过PRIMARY KEY约束 和 UNIQUE 约束进行强制;域完整性可通过CHECK 约束进行强制;引用完整性(Referential Integrity)则应通过 FOREIGN KEY 约束进行强制。 当约束支持的功能无法满足应用程序的功能要求时,DML 触发器则表现为比约束更为精细和强大的数据控制能力。

1) 约束通常通过标准化的系统错误信息来传递错误消息,DML触发器可自定义消息和错误处理。

2) 若未使用REFERENCES 子句定义级联引用完整性约束,则可通过DML 触发器将更改或删除以级联方式传递给数据库中的相关表。

3) DML触发器可根据应用程序的需要定义比CHECK 约束定义的限制更为复杂的其他限制。

4) DML 触发器可以防止恶意或错误的 INSERT、UPDATE 以及 DELETE 操作。例如,可通过触发器对不可更新视图进行数据操纵。

4 DML触发器工作原理

触发器由时间条件、触发事件和动作组成。确定触发器的逻辑结构,就是确定触发器的时间条件、触发事件和动作以及触发器的选项[7]。将触发器和触发它的语句作为可在触发器内回滚的单个事务对待。如果检测到错误则整个事务即自动回滚[8]。在使用触发器过程中,因触发器被触发后所产生的Inserted和Deleted两张逻辑表发挥着重要作用。它们具有只读性,并在触发器执行完毕后从内存中删除,而非实际存储在数据库中的物理表。这两张表的表结构与触发器所在的数据表结构完全一致。endprint

若触发事件为Insert操作,触发器被触发后,将对触发器所属表新增记录的副本填充至Inserted表中;若触发事件为Update操作,触发器被触发后,将对触发器所属表被修改记录更新后的副本填充至Inserted表中,将被修改记录更新前的记录副本填充至Deleted表中;若触发事件为Delete操作,触发器被触发后,将对触发器所属表中被删除记录的副本填充至Deleted表。通过这两张逻辑表,可了解数据在被操作前后的差异状态,并基于此差异采取行动。

5 DML触发器的应用

下面以学生成绩管理库(PXSCJ)为例,说明触发器在数据完整性方面的具体应用。PXSCJ库包含学生信息表XSB(学号,姓名,性别,出生年月,专业,总学分,备注);课程信息表KCB(课程号,课程名,开课学期,学时,学分);成绩CJB表(学号,课程号,成绩)。

5.1 强制参照完整性

在从表中创建触发器,当向从表插入新记录或更新记录时,触发器被触发,检查假设插入或更新操作完成后,从表中外键的数据是否存在于主表中的主键或唯一键,若不存在则插入或更新操作不允许被执行。同时,代码设计应满足于多行记录同时被插入的情况。如为保证向成绩表CJB插入或更新记录后,该记录的学号能存在于学生信息表XSB、课程号能存在于课程信息表KCB,创建触发器CJB_ trigger。实现过程如下:

5.2 级联更新或删除

当需要实现主从表数据级联一致时,可直接基于从表创建外键约束,但由于外键约束会导致当需要对主表的主键或唯一键进行修改或删除操作时无法执行。因此,通过创建触发器,可实现主从表级联更新或删除,从而提高数据操作的灵活性。如:当修改学生信息表XSB中某个学生的学号时,能实现级联修改该生在成绩表CJB中对应的记录的学号;当删除学生信息表XSB中某个学生的记录时,能实现级联删除该生在成绩表CJB中对应的记录,创建触发器XSB_delup。同理,当修改课程信息表KCB中某门课程的课程号时,能实现级联修改该生在成绩表CJB中对应的记录的课程号;当删除课程信息表KCB中某门课程的记录时,能实现级联删除该生在成绩表CJB中对应的记录,创建触发器KCB_delup。实现过程如下:

5.3 实现用户定义业务规则

在数据库里,数据表之间经常会出现某些数据列相互之间存在业务规则上的相关性,则可通过创建触发器提高维护效率。当对表间相关列的数据进行增、改、删的操作时,能同时自动更新对应列的数据,使相关列之间的数据自动保持一致,从而降低人工维护成本。如:在学生信息表XSB、学生成绩表CJB、课程信息表KCB中,有一个相关三张表的特殊列,即学生信息表XSB的总学分。当对CJB进行增、改、删成绩时,或对KCB的学分列进行修改时,要求XSB的总分列要实现同步更新。利用触发器让其实现自动更新,保证相关列数据的一致性。

1) 向学生成绩表CJB添加学生课程成绩时,若成绩大于等于60时,即可获得相应的学分,并重新累计于学生信息表XSB中的总学分列,当删除学生成绩表CJB中的记录时,学生信息表XSB中的总学分应亦能自动发生更新。当对CJB表进行更新操作时,若修改列仅为课程号或成绩时,则只需获得记录在被修改前后的总学分差值,然后累加至XSB表中对应记录的原总学分即可。但若修改列为学号,则需修改XSB表中两个学生的总学分。因此,必须对触发器CJB_trigger进行进一步优化和整合,最后代码为:

5.4 更新不可更新视图

在PXSCJ数据库中创建视图stu_view,包含学号、姓名、专业、课程号、课程名、成绩。该视图依赖于基表XSB、CJB、KCB,属不可更新的视图。通过在视图上创建instead of触发器,当向视图插入数据时,分别向XSB、CJB、KCB插入数据,从而实现向视图插入数据的功能。

6 结束语

通过上述实例可知,触发器在维护数据库数据完整性时表现出强大的功能,尤其对于处理较为复杂的业务规则定义时所具备的灵活性,大大提高了数据库系统的开发效率。值得注意的是触发器不可滥用,尤其是当形成触发器链的时候容易出现连环触发而导致错误,并造成不必要的损耗[9]。

参考文献:

[1] 360百科.数据完整性[EB/OL].(2014-04-14). http://baike.so.com/doc/5858667.html.

[2] 刘艳春.运用SQL Server 开发软件参照完整性实现方法[J].计算机技术与发展,2013,23(6):117-121.

[3] Behrend A,Doranc,Manthey R.SQL Triggers Reacting on Time Events:An Extension Proposal[C]//Proceedings of the 13th East European Conference on Advances in Databases and Information Systems,2009.

[4] 王珊,萨师煊.数据库系统概论[M].4版.北京:高等教育出版社,2006:160-163.

[5] Natarajan J,Bruchez R,Shaw S,et al. Pro T - SQL 2012 programmers guide[ M] . GRE:Springer,2012.

[6] 贝尔实验室.数据库系统概念[M].4版.北京:机械工业出版社,2003:161.

[7] Fakas G J,Cawley B,Cai Zhi.Autom ated Generation of Personal Data Reports from Relational Databases[J].Journal of Information &Knowled ge Management (JIKM ),2011,10(2) :193-208.

[8] MSDN.DML触发器[EB/OL].(2014-04-14). http://msdn.microsoft.com/zh-cn/library/ms178110.aspx.

[9] 西尔伯沙茨.数据库系统概念[M]. 6版.北京:机械工业出版社,2012:143.endprint