首页 > 代码库 > 浅入浅出触发器
浅入浅出触发器
1、触发器的使用背景
做完机房收费系统个人重构之后只用了存储过程,最近在看牛腩视频讲到触发器的使用,当时就遇到过外键约束不能删除、有关联的表记录的问题,当时的解决方法有的使用了存储过程,或者是标记相关联的约束键不可用。其实触发器和存储过程的使用的相似的,可以说触发器就是一种特殊类型的存储过程。
举个机房收费系统中的例子:
截取一部分数据库关系图:
当想要删除一个用户时,该用户充值和退卡的记录就会受到影响。这时就会出现外键约束的错误。
这是因为充值和退卡表都和用户表的用户ID属性有关系,当删除用户表中一个用户时,应该连同删除充值表和退卡表中该用户ID的记录。这样才不会楚翔这种错误。当我们需要删除一个表的级联的所有表时,触发器就闪亮登场了。
2、触发器的应用
拿新闻发布系统来说,数据库设计图如下所示:
当药删除新闻类别时,该新闻类别下有相关的新闻,每条新闻下又有很多条新闻评论。我们需要在删除一条新闻类别时同时删除掉该news表中该id的新闻,同时删除comment表idnewsId是该新闻的评论。
使用触发器如下:
在新闻类别表现创建存储过程:因为是删除新闻类别,即删除就是触发点。
-- ============================================= -- Author: 许丹 -- Create date: 2014-7-18 -- Description: 删除类别触发器 -- ============================================= ALTER TRIGGER [dbo].[trigCategoryDelete] -- 触发器名称 ON [dbo].[category] --操作的数据库表 instead of DELETE --用下面的语句代替删除语句 AS BEGIN -- --删除该类别下的所有新闻 --delete news where caId in (select id from deleted) declare @caId int select @caId=id from deleted --删除评论 delete comment where newsId = (select newsId from news where caId =@caId) --删除新闻 delete news where caId =@caId --先删除该类别下的所有新闻 --删除类别 delete category where id=@caId --再删除该类别 END
对三条删除语句的解释:
首先声明一个@id变量,当删除一条新闻类别时
delete from category where id=6这是一个触点,这时并不直接删除类别,而是触发这个触发器。用触发器下面的删除语句代替这个删除操作。首先选择被删除的新闻类别的ID,然后删除该新闻ID下的所有评论,在删除该类别下的所有新闻,最后删除该类别。这样就解决了级联删除的效果。
其实触发器和存储过程的创建一样,有它特定的语句,下面简单的谈谈我对触发器的理解:
3、触发器的概念:
触发器是一类特殊的存储过程,在对表或者视图进行增删改操作时,它就会被激发开始运行,有时,触发器也可以解释为自动执行的存储过程。一触即发。
- 触发器自动执行。
- 触发器能够对数据库中的相关表实现级联更改。触发器基于一个表,但可以实现多表操作,实现相关表的级联操作。
- 触发器可以实现比CHECK约束更为复杂的数据完整性约束。
- 触发器可以评估数据修改前后的表的状态,并根据其差异采取对策。
- 一个表中可以同时存在三个不同操作的触发器(insert、update、delete),对于同一个修改语句可以有多个不同的相应对策。
5、慎用触发器器
触发器功能强大,轻松可靠地实现许多复杂的功能,为什么又要慎用呢。触发器本身没有过错,但由于我们的滥用会造成数据库及应用程序的维护困难。在数据库操作中,我们可以通过关系、触发器、存储过程、应用程序等来实现数据操作…… 同时规则、约束、缺省值也是保证数据完整性的重要保障。如果我们对触发器过分的依赖,势必影响数据库的结构,同时增加了维护的复杂程度。
总结:
看牛腩视频有种相见恨晚的感觉,人类真的是很强大,让我们的编程语言越来越简单,实现的功能越来越强大,昨天听一个是个讲关于机房合作的经验,中间提到EA的强大,数据库的设计是越来越简单,EA可以生成代码,可以导出数据库,当时的感觉就是自己的知识真的匮乏,很多没有动手尝试,用一些很笨的方法。触发也是这样,级联的表如果是一个两个还好说,要是一百个(当然这就数据库冗余了,应该没有这样的数据库),就太麻烦了。编程仍未结束,要实现更好更高效率的,更简单的解决方法是我们的努力方向。