日期:2014-05-17 浏览次数:20993 次
在数据库中我们所面对的绝大多数都是关联表,表与表之间通过外键相互关联成一个“联盟”,在我们对数据表中的数据进行删除操作时往往会因为外键的作用牵一发而动全身,使得操作失败。说到这我们首先简单的来了解一下表间关联。
如上图中所示的三张表,分别代表的是guojia表(国家),sheng表(省),shi表(市)。在sheng表与guojia表之间,guojia表为主键表,sheng表为外键表,通过将sheng表中的suoshuguojia字段与guojia表中的id字段相互关联将两张表关联起来,表明sheng从属于某一个guojia。同样通过将shi表中的suoshusheng字段与sheng表中的id字段相互关联将两张表关联起来,表明shi从属于某个sheng。这样三张表之间就建立了关联,于是我们希望在删除guojia表中某条记录同时删除属于该国家的省连同属于该省的市的时候便会出现如下错误提示:
消息547,级别16,状态0,第1 行,DELETE 语句与REFERENCE约束"FK_chengshi_guojia"冲突。该冲突发生于数据库"newssystem",表"dbo.sheng",column'suoshuguojia'。语句已终止。
稍懂英文的人都可以看明白这显然是由于外键的作用而导致的删除失败,那么我们究竟怎样才能达到级联删除的目的呢?别着急,下面我就为大家引荐三位剑客来帮助大家解决这个问题:
一、踏雪无痕----触发器
首先我们先来了解一下触大侠的简历:
触发器可以说是一种特殊的存储过程,但它并不像一般存储过程那样供外界调用,它是通过事件来触发的。触发器分为两种,分别是instead of触发器和after触发器。能够引发触发器的触发事件则有三种分别是insert、update和delete事件。After触发器指的是当触发事件发生的时候,先执行该事件,然后再执行预设代码,instead of触发器指的是当触发事件发生后并不执行该触发事件,而是越过触发事件执行预设代码。下面我们就做一个触发器来实现数据的级联删除:
CERATETRIGGER [shanchu] ON [dbo].[category] instead of DELETE AS BEGIN --声明一个变量 Declare @caid int --给变量赋值 Select @caid=id from deleted --删除市 Delete shi where id=(selectsuoshusheng from sheng where suoshuguojia=@caid) --删除省 Delete sheng wheresuoshuguojia=@caid --删除国家 Delete guojia where id=@caid End
可能有的同学会问,为什么要用instead of触发器而不用After触发器呢?这还得从级联删除的机制说起。当我们执行级联删除操作时,它会一级一级的向下查找,如我们执行语句 dele