`
zhaole609
  • 浏览: 339550 次
  • 性别: 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语句创建触发器

    例如当对某一表进行诸如`UPDATE`(修改)、`INSERT`(插入)、`DELETE`(删除)这些操作时,SQL Server 就会自动执行触发器所定义的`SQL`语句,从而确保对数据之间的相互关系,实时更新. 触发器的主要作用就是其能够实现由 ...

    postgresql-15.2-2-windows-x64.zip

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

    Oraclet中的触发器

    触发器是许多关系数据库系统都提供的一项技术。在ORACLE系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的PL/SQL块,不过有一点不同的是,触发器是隐式调用的,并不能接收参数。 触发器优点 (1)...

    MySQL使用外键实现级联删除与更新的方法

    主要介绍了MySQL使用外键实现级联删除与更新的方法,详细分析了mysql数据库与表的创建、数据插入、查询以及外链的使用与级联操作相关技巧,需要的朋友可以参考下

    浅谈基本触发器的逻辑结构和工作原理

    如果使用数据库关系图,则可以在表之间创建关系以自动创建外键约束。  触发器功能强大,轻松可靠地实现许多复杂的功能,为什么又要慎用呢。触发器本身没有过错,但由于我们的滥用会造成数据库及应用程序的维护困难...

    SQL Server 2000数据库中实现数据参照完整性的方法分析.pdf

    参照完整性是指一个实体与其他实体之间的关系,例如,一个订单与客户之间的关系。域完整性是指一个实体的每个属性的正确性,例如,一个客户的名字必须是字符串类型。 数据完整性的类型 数据完整性可以分为以下几种...

    postgresql-11.4-2-osx.dmg

    PostgreSQL支持大部分的SQL标准并且提供了很多其他现代特性,如复杂查询、外键、触发器、视图、事务完整性、多版本并发控制等。同样,PostgreSQL也可以用许多方法扩展,例如通过增加新的数据类型、函数、操作符、...

    基础电子中的浅谈基本触发器的逻辑结构和工作原理

    如果使用数据库关系图,则可以在表之间创建关系以自动创建外键约束。  触发器功能强大,轻松可靠地实现许多复杂的功能,为什么又要慎用呢。触发器本身没有过错,但由于我们的滥用会造成数据库及应用程序的维护困难...

    关系数据库原理及应用课程设计基于VB和SQL Server实现的题库管理系统源码+数据库设计

    关系数据库原理及应用课程设计基于VB和SQL Server实现的题库管理系统源码+数据库设计 ...注:考虑到要进行级联删除,没有设置外键,用触发器约束。 如题目表中存在题型外键,题型表中无法删除题目中写入的题型

    搜索引擎的设计与实现.rar

    2)它的图形化界面可以很快的建立表与表之间的联系图,一个表的外键关系可以很快地建立出来; 3)有很强大的安全机制,有自己的导入导出格式,很安全; 4)具有强大的功能,事务操作等等。 它也存在的缺点:在...

    关系型数据库元数据获取工具db-meta.zip

    db-meta 是关系型数据库元数据获取工具,把数据库->schema->表->列,主键、外键、索引,触发器、存储过程、函数等抽象为对象,易于使用方便序列化。  1、 提供丰富的接口,能够获取常见的所有数据库元数据。...

    Transact-SQL编程规范

    1.3.13. 主键、外键关系和索引 8 1.4.参数命名 9 1.4.1. 数据列参数 9 1.4.2. 非数据列参数 9 1.5.常见命名 9 1.5.1. 常用字段命名 9 2.SQL编写 10 2.1.大小写 10 2.2.使用“;” 10 2.3.存储格式 11 2.4.类型选择 11...

    PostgreSQL关系型数据库管理系统

    PostgreSQL是一个功能非常强大的、源代码开放的客户/服务器关系型数据库管理系统(RDBMS),是一个非常健壮的软件包,有很多在大型商业RDBMS中所具有的特性,包括事务、子选择、触发器、视图、外键引用完整性和复杂...

    使用MySQL设计企业OA系统的数据库课程设计文档

    这些表通过主键和外键建立了关系,例如员工表和部门表之间存在一对多的关系,一个部门可以有多个员工,每个员工只属于一个部门。公文表和员工表之间存在多对一的关系,一个员工可以发布多个公文,每个公文只有一个...

    数据库系统原理实验.docx

    《数据库理论与应用》实验报告 数据库系统原理实验全文共8页,当前为第1页。实验序号:4 实验项目名称:数据完整性控制 数据库系统原理实验全文共8页,当前为第1页。 学 号 姓 名 专业、班 实验地点 指导教师 ...

    JAVA医院挂号系统毕业设计源码+选题介绍+功能需求+技术要求分析等内容

    使用SQL Server或MySQL作为后台数据库,依据数据库设计过程及规范,设计数据库表结构及主外键关系,并结合功能需求适当设计存储过程和触发器;采用面向对象设计方法学,运用所学的面向对象分析设计方法,以及对应的...

    PostgreSQL(postgresql-14.1.tar.gz)

    PostgreSQL(postgresql-14.1.tar.gz) PostgreSQL是一种特性非常齐全的自由软件的...PostgreSQL支持大部分的SQL标准并且提供了很多其他现代特性,如复杂查询、外键、触发器、视图、事务完整性、多版本并发控制等。

    PostgreSQL(postgresql-13.5.tar.gz)

    PostgreSQL(postgresql-13.5.tar.gz) PostgreSQL是一种特性非常齐全的自由软件的...PostgreSQL支持大部分的SQL标准并且提供了很多其他现代特性,如复杂查询、外键、触发器、视图、事务完整性、多版本并发控制等。

    PostgreSQL(postgresql-14.1.tar.bz2)

    PostgreSQL(postgresql-14.1.tar.bz2) PostgreSQL是一种特性非常齐全的自由软件的...PostgreSQL支持大部分的SQL标准并且提供了很多其他现代特性,如复杂查询、外键、触发器、视图、事务完整性、多版本并发控制等。

    PostgreSQL(postgresql-13.5.tar.bz2)

    PostgreSQL(postgresql-13.5.tar.bz2) PostgreSQL是一种特性非常齐全的自由软件的...PostgreSQL支持大部分的SQL标准并且提供了很多其他现代特性,如复杂查询、外键、触发器、视图、事务完整性、多版本并发控制等。

Global site tag (gtag.js) - Google Analytics