触发器就是一种特殊的存储过程,和一般的存储过程的不同就是不能直接调用,而是当触发某个事件的时候就自动激活了,就像窗体有的Load事件,只要窗体一加载,事件立即触发一样,当涉及到触发器所写的事件过程时就立即触发这个事件。
触发器用是一种强制业务规则和保证了数据完整性的机制。当触发器所保护的数据发生变化,就立即被激活,执行一定的操作,从而保证数据的完整性。
下面我介绍的实例是使用触发器完成级联的删除:
数据库关系图:
其中news表中的caId字段是该表的外键,连接着category表中的id字段,comment表中newsid是该表的外键,连接着news表中的id
要求是删除新闻类别就连同其下的所有新闻和每个新闻的评论都要一起删除,由于主键和外键的作用,我们在添加或者删除一条记录的时候会出现如下的错误
导致添加或者删除失败,下面介绍如何通过触发器避免着这种问题。
如图所示,在数据库中建立触发器:
编写触发器:
-- =============================================
-- Author: 肖红
-- Create date:2014-6-6
-- Description: 删除类别触发器(连同其下的新闻以及新闻的评论一起删除)
-- =============================================
CREATE TRIGGER [dbo].[trigCategoryDelete]
ON [dbo].[category]
instead of DELETE
AS
BEGIN
declare @caId int
select @caId=id from deleted
--删除评论
delete comment where newsId in(select newsId from news where caId=@caId)
--删除新闻
delete news where caId=@caId
--删除类别
delete category where id=@caId
END
分析这段代码的含义:
在与外键关联的表中建立的触发器,CREATE TRIGGER [dbo].[trigCategoryDelete]
ON [dbo].[category]
建立触发器之后,当你删除一个表的时候,触发器会自动建立一个表(类似于临时表)来储存你将要删除的信息,此时这个表名称就是DELETE
声明传入的变量(与外键相关): declare @caId int
然后从这个临时表中选择出类别id赋给变量@id的(即你要删除的类别的id):select @caId=id from deleted
先删除这些新闻其下的评论:
delete commentwhere newsId in(select newsId from news where caId=@caId)
由于一个新闻下不只有一条评论,所有在删除多条评论的时候我们在SQL语句中使用“in”。
在删除新闻,最后删除类别。
AFTER和INSTEAD OF的区别:
AFTER:简单的意思就是删除之后再执行下面的语句,如果不能删除,则不会执行到触发器。(在这里由于外键的关系根本不能删除,所有使用AFTER根本不会执行到触发器,所以这里不用AFTER)
instead of :理解为触发器语句代替了原来的语句,执行触发器,然后执行原来的语句操作。
根据触发器执行的顺序关系,我们在这里使用instead of
触发器的好处不只有这些,触发器可以禁止或回滚违反引用完整性的更改,从而取消所尝试的数据修改。当更改外键的新值与主键不匹配时,触发器就发挥作用了。