`
zhaole609
  • 浏览: 343564 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类
最新评论

触发器与外键关系

 
阅读更多
在项目进行过程中,碰到了一个比较棘手的问题,惊讶于sql server为什么没有这样的功能,简单察看了下其他商业数据库产品,好像也没有这样的功能,于是纳闷,这个有这么难实现吗,还是有其他原因故意不实现?
以下是一个简化的模型,其中,Comments中的每一行只能属于People或Book,即BookId与PeopleId只能是其中一个有值,另一个为空。

http://www.blue1000.com/bkhtml/2008-09/57985.htm

问题出在级联删除上,我要的是以下两个逻辑:
  
1、删除People时,级联删除Book与Comments
  
2、删除Book时,级联删除Comments
  
  
  
      粗一看,好像很简单,把那三个外键设为级联删除就OK了,但是,不行,设不进去,原因是“可能会导致循环或多重级联路径。请指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。”初一想,好像sql server做的也对,它又不知道你的Comments只可能属于People或Book,不可能同时属于People和Book,如果同时属于,另外,这个属于的Book又正好属于那个People时,那么这个Comments不就得被级联删除两次?可是,这个严重吗?似乎不严重,Sql Server应该可以记录一个Comments被级联删除的次数,那么你删除一次不就完了,再不行,你也就甭记录,直接在删除People时删掉级联掉Comments,然后级联删除Book时,就找不到要被再次级联删除的那个Comments了,那不也OK?可是Sql Server没有选择这样做,它选择了阻止这种级联的发生,我不知道为什么。
      那既然这条路不同,那么我就想着用触发器来做。首先,我设置了People与Book之间为级联删除,为People与Comments、Book与Comments之间设置了“No Action”这样的外键。然后我写下了以下这样的触发器:
  
  
  
   create trigger PeopleCascadeDelete
   on People
   after delete
   as
   begin
   delete from Comments where PeopleId in (select id from deleted)
   end
可是,不行,原因是,该触发器是在People删除之后执行的,而由于外键的关系,在对应的Comments没有删除之前,People自身没法删除,于是这就导致了一个死循环。我们应该先删除掉对应的Comments,然后再删除People。然而,我翻查了联机文档,也google了一把,好像说sql server只支持事后触发,不支持事前触发,也就是说,在People被删除之前,没法触发触发器。晕倒,为什么Sql Server不知道事前触发呢?(也是支持,但是我没有找到,因为不存在“before delete”这样的句子,那个“for delete”,好像跟“after delete" 是一样的作用,不知道我没有理解错。)
  
于是接下来,我想到了使用“Instead of delete”,即用这个触发器完全代替delete的操作,这样真正的delete people语句就不会执行了,但是我可以在触发器中先删除对应的Comments,然后在触发器中补上delete people操作。语句如下:

create trigger PeopleCascadeDelete
   on People
   instead of delete
   as
   begin
   delete from Comments where PeopleId in (select id from deleted)
   delete from People where Id in (select id from deleted)
   end
  
该语句通过,暗喜了一把,于是如法炮制到Book,问题来了,“无法对表 'Book' 创建 INSTEAD OF DELETE 或 INSTEAD OF UPDATE 触发器 'BookCascadeDelete'。这是因为该表的外键使用级联删除或级联更新。”sql server非常有道理,你删除People时,是要级联删除Book的,但是你把Delete语句给Instead了,那就不能保证book被级联删除了。
  
My God。我想我这个表结构不是个设计的很差的表结构吧,问题也不是个大问题吧,但是怎么就这么麻烦呢???非得把Comments拆成两张表吗,这样对我的麻烦更大(实际的Comments有很多字段,而且,与Comments关联的表不止两个,而是很多个,以后还可能增加)?

分享到:
评论

相关推荐

    SQL Server中约束与触发器差异比较.pdf

    DEFAULT(默认约束)用于为列提供默认值,CHECK(检查约束)确保列的值满足特定条件,NOT NULL(非空约束)阻止输入NULL值,UNIQUE(唯一约束)确保列值的唯一性,以及FOREIGN KEY(外键约束)用于维护表间的关系和...

    Oracle触发器实验报告

    在本实验报告中,主要涉及了Oracle触发器与参照完整性约束的关系,以及在违反约束时触发器如何影响数据插入。 参照完整性约束是数据库设计的基本原则之一,确保了数据的一致性和准确性。在这个实验中,有两个相关的...

    触发器数据库实用全套PPT.ppt

    5. 触发器可以维护非规范化数据,非规范数据通常是指在表中的派生、冗余的数据值维护非规范化数据应该通过使用触发器来实现表的级联是指不同表之间的主外键关系,维护表的级联可通过设置表的主键与外键的关系来实现...

    SQL Server中触发器与约束的应用比较.pdf

    触发器与约束在应用上各有特点和适用场景,下面将详细介绍这两者的功能、应用以及相互之间的比较。 首先,约束是SQL Server中的内建机制,它可以直接作用于表的列上,以确保数据满足特定条件。约束可以分为多种类型...

    快速理解MySQL中主键与外键的实例教程

    在MySQL数据库中,主键和外键是关系型数据库设计中的关键概念,它们用于确保数据的一致性和完整性。本文将深入解析这两个概念以及它们之间的联系。 首先,让我们了解什么是主键。主键(Primary Key)是数据库表中一...

    postgresql-15.2-2-windows-x64.zip

    PostgreSQL是一个开源的关系型数据库管理系统,它提供了许多高级特性,如多版本并发控制、事务、触发器、外键约束等。PostgreSQL还支持多种数据类型,包括地理空间数据类型,可以通过PostGIS扩展进行管理和分析。 ...

    关系数据库系统RDBS

    "关系数据库系统RDBS" 关系数据库系统(RDBS)是一种基于关系模型的数据库管理系统。关系模型是用二维表格结构来表示实体及实体之间的...关系数据库系统中的完整性约束、视图、触发器、外键约束等都是非常重要的概念。

    SQL server创建触发器实现级联删除

    - **产品类别表**与**具体产品表**之间的关系:当删除某个类别时,需要同时删除该类别下的所有产品。 - **部门表**与**员工表**的关系:如果一个部门被撤销,则该部门下的所有员工记录也需要被清除。 #### 三、级联...

    SQL Server2008中级联的实现原理探讨——以触发器为例.pdf

    参照完整性是关系数据库理论中的基本概念,它规定了一个表(参照关系)中的外键字段必须对应另一个表(被参照关系)的主键值。在SQL Server 2008中,可以通过定义外键约束来实现级联操作。例如,在员工管理和部门...

    MySQL的约束-外键约束

    外键约束允许一个表中的数据引用另一个表中的数据,这种引用关系通常是主键与外键之间的对应。主键(Primary Key)在一个表中是唯一的,而外键(Foreign Key)则是指向另一个表主键的引用,这样就形成了两个表之间的...

    数据完整性、主键和外键、数据类型

    - **参照完整性**:参照完整性涉及到表与表之间的关系,即当两个表通过公共字段(通常为外键)关联时,确保这些字段之间的一致性。如果一个表的外键指向另一个表的主键,则在删除或更新主表中的主键值时,需要考虑对...

    浅谈SQL Server触发器功能与应用技巧.pdf

    6. 在包含使用DELETE或UPDATE操作定义的外键的表中,不能定义INSTEAD OF和INSTEAD OF UPDATE触发器。 7. TRUNCATE TABLE语句不会引发DELETE触发器,WRITETEXT语句也不会引发INSERT或UPDATE触发器。 触发器的应用中...

    MySQL触发器代码

    这些表之间的关系可以通过外键进行关联。例如,Student表中的DEPTNO字段引用了Dept表中的DEPTNO字段,Sc表中的SNO和CNO分别引用了Student表中的SNO和Course表中的CNO。 #### 三、触发器实例分析 接下来我们来详细...

    触发器技术在SQL Server 2000中的应用.pdf

    1. 触发器与完整性约束:虽然触发器可以用来维护数据完整性,但它们与数据库表上定义的完整性约束(如主键、外键、唯一性约束等)不同。完整性约束是数据库系统自动检查的,而触发器则执行更复杂的数据验证逻辑。 2...

    基于SQL Server触发器的数据完整性应用.pdf

    外键约束将一个表中的某些列与另一个表中的主键列关联起来,确保了表间的一致性关系。外键列必须参照主键列,从而保持两个表中数据的对应关系。 域完整性通过检查约束来实现,检查约束可以定义对列或表中记录的输入...

    SQL Server触发器在数据完整性和安全方面的应用.pdf

    而 INSTEAD OF 触发器与 AFTER 触发器不同,它在触发它的操作执行之前执行,相当于替代了原有的数据修改操作,常用于处理复杂的业务逻辑或者在某些情况下替代标准的外键约束功能。 在数据库安全方面,触发器的作用...

Global site tag (gtag.js) - Google Analytics