分享

触发器--特殊的存储过程

 昵称10504424 2013-02-20
 很多人应该都用过存储过程和触发器,而触发器并不是一个新的概念,它只是一个特殊一些的存储过程, 它可以根据执行的TQL 语句自动执行,不需要我们去调用。

           触发器是为了数据库表结构的完成性、一致性而使用的,和单个表的约束一样,触发器是对于表之间的约束,它比主键约束范围更广泛一些,作用范围更大一些,下面给大家介绍一下常用的三种触发器.

 

           【插入触发器(Insert Trigger)】

           当向表里面插入记录时候触发

           通过临时表(Inserted)来实现,我们需要往表里插入一条记录时,插入的记录先插入到临时表中,然后,从临时表插入到目标表中,为什么采用临时表,我觉的是因为触发器是自动触发,既然是自动触发就不会往里面传参数,那么参数怎么传入到目标表中呢,为了传入参数加入了临时表,将要插入或者删除的记录先放到了临时表中,再从临时表插入数据。

 

          下面是一个校区的基本表TB_Campus,向表里插入数据时触发该触发器,自动向该小区下的建筑表TB_Building添加数据记录,从而保证这两个表的数据一致性。

           触发器通常是为了两个表或多个表中数据一致加入的。

          例如:

 

           【更新触发器(Update Trigger)】

            当更新表中的任意一个字段时触发

            更新触发器需要用到两个表,一个是Inserted 表,另一个是Deleted表,Inserted表存储更新后的记录,Deleted表存储更新后的记录,更新一个表示需要先将要删除的记录放入Deleted表中,然后,将Inserted表的新记录插入表中,从而实现更新操作。

 

            例如:下面是教务系统中一个触发器,更新老师课程关系表(TR_TeachCourseLink)记录,并更新与这个表有关的表。

 

            在更新、删除触发器中我们需要注意一个问题,触发器为什么会触发呢,它是基于SQL 语句而执行的,但更新、删除语句可以一次性删除多条记录,其实SQL 语句只执行了一次,即触发器也只执行一次,那么当涉及到表关系为一对多或者多对多时,就会出现更新或删除不完下面表中记录

          

            为了解决这一问题,我们在下面存储过程中加入了游标,使得更新或删除记录时一条一条的删除,每删除一条,触发器就会执行一次,使得数据保持一致,不过,这样可能大大降低了SQL语句执行速度,如果数据量很大,速度会变慢。

 

  1. <SPAN style="FONT-SIZE: 18px">USE [BasicDataSystem]  
  2. GO  
  3. /****** Object:  Trigger [dbo].[TR_TeachCourseLink_US]    Script Date: 2013/1/2 19:28:42 ******/  
  4. SET ANSI_NULLS ON  
  5. GO  
  6. SET QUOTED_IDENTIFIER ON  
  7. GO  
  8. -- =============================================   
  9. -- Author:      评教小组-李龙生   
  10. -- Create date:      2012年12月30日21:03:26   
  11. -- Description:  假删除授课表中课表记录   
  12. --                   授课课程与虚拟班关系、虚拟班   
  13. --           授课课程与上课班学生关系、上课班学生   
  14. --                   课程与选修课学生关系、选修课学生   
  15. -- =============================================   
  16. ALTER TRIGGER [dbo].[TR_TeachCourseLink_US]  
  17.       
  18.     ON [dbo].[TBR_TeachCourseLink]  
  19.   
  20.     AFTER Update  
  21. AS  
  22.       
  23.     DECLARE  
  24.     @err1 INT,                   --存储错误号   
  25.     @err2 INT,  
  26.     @err3 INT,  
  27.     @err4 INT,  
  28.     @err5 INT,  
  29.     @err6 INT,  
  30.     @err7 INT,  
  31.     @Indexing INT,               --授课课程主键   
  32.     @TeachClassID VARCHAR(36),   --虚拟班主键   
  33.     @StudentID VARCHAR(36)       --学生主键   
  34.   
  35. BEGIN  
  36.   
  37.     --选择要删除授课课程记录的主键   
  38.     SELECT @Indexing=Indexing FROM  <SPAN style="COLOR: #3333ff"><STRONG>deleted    --删除临时表   
  39. </STRONG></SPAN>      
  40.     --开启事务   
  41.     BEGIN TRANSACTION  
  42.   
  43.         /*更新授课课程记录、授课课程与虚拟班关系、虚拟班,各表中的IsAvailable   
  44.         字段为 “否”*/  
  45.   
  46.         --更新授课课程记录 IsAvailable='否'   
  47.         UPDATE TBR_TeachCourseLink SET IsAvailable='否' WHERE Indexing=@Indexing  
  48.         SET @err1=@@ERROR  
  49.   
  50.         --更新虚拟班与TeachCourse表的关系 IsAvailable='否'   
  51.         UPDATE TBR_CourseTeachClassLink SET IsAvailable='否' WHERE Indexing=@Indexing  
  52.         SET @err2=@@ERROR  
  53.   
  54.         --更新虚拟班表 IsAvailable='否'(需要触发多条记录,用游标操作)   
  55. <SPAN style="COLOR: #cc33cc"><STRONG>       --声明游标   
  56.         DECLARE TeachClassCursor CURSOR FOR    
  57.         SELECT TeachClassID FROM TBR_CourseTeachClassLink  WHERE Indexing=@Indexing   
  58.         --打开游标   
  59.             OPEN TeachClassCursor  
  60.                 FETCH NEXT FROM TeachClassCursor INTO @TeachClassID  --给变量赋初始值   
  61.                 WHILE @@FETCH_STATUS=0 --语句执行成功   
  62.                     BEGIN  
  63.                     --更新中的记录   
  64.                     Update TB_TeachClass SET isAvailable = '否' WHERE TeachClassID=@TeachClassID   
  65.                     FETCH NEXT FROM TeachClassCursor INTO @TeachClassID  
  66.                     END  
  67.             --关闭并释放游标   
  68.             CLOSE TeachClassCursor  
  69.         DEALLOCATE TeachClassCursor  
  70. </STRONG></SPAN>        SET @err3=@@ERROR  
  71.   
  72.         /*更新授课课程与选修课学生关系、学生表,各表中的IsAvailable   
  73.         字段为 “否”*/  
  74.         --更新授课课程与选修课学生的关系表IsAvailable='否'   
  75.         UPDATE TBR_StuChooseCourseLink SET IsAvailable='否' WHERE Indexing=@Indexing  
  76.         SET @err6=@@ERROR  
  77.   
  78.         --更新学生表,将IsAvailable字段变为'否'(需要触发多条记录,用游标操作)   
  79.         --声明游标   
  80.         DECLARE StudentCursor CURSOR FOR    
  81.         SELECT StudentID FROM TBR_StuChooseCourseLink  WHERE Indexing=@Indexing   
  82.         --打开游标   
  83.             OPEN StudentCursor  
  84.                     FETCH NEXT FROM StudentCursor INTO @StudentID  --给变量赋初始值   
  85.                     WHILE @@FETCH_STATUS=0 --语句执行成功   
  86.                     begin  
  87.                     --更新中的记录   
  88.                     Update TB_Student SET isAvailable = '否' WHERE StudentID=@StudentID  
  89.                     FETCH NEXT FROM StudentCursor INTO @StudentID  
  90.                     end  
  91.             --关闭并释放游标   
  92.             CLOSE StudentCursor  
  93.         DEALLOCATE StudentCursor  
  94.         SET @err7=@@ERROR  
  95.   
  96.     --判断是否执行成功   
  97.     IF (@err1 =0 and @err2=0 and @err3=0 and @err4=0 and @err5=0 and @err6=0 and @err7=0)  
  98.         --提交事务   
  99.         COMMIT TRANSACTION  
  100.     ELSE  
  101.         --事务回滚   
  102.         ROLLBACK TRANSACTION  
  103.   
  104.   
  105. END</SPAN>  

 

           【删除触发器(Delete Trigger)】

            当删除表中记录时触发

            先把要删除的记录放到Deleted临时表中,然后,再删除。

             例如:

  1. <SPAN style="FONT-SIZE: 18px">USE [BasicDataSystem]  
  2. GO  
  3. /****** Object:  Trigger [dbo].[TR_TeachCourseLink_D]    Script Date: 2013/1/2 19:29:42 ******/  
  4. SET ANSI_NULLS ON  
  5. GO  
  6. SET QUOTED_IDENTIFIER ON  
  7. GO  
  8. -- =============================================   
  9. -- Author:      评教小组-李龙生   
  10. -- Create date:      2012年12月30日21:03:26   
  11. -- Description: 彻底删除授课表中课表记录   
  12. --                   课程与选修课学生关系、选修课学生   
  13. -- =============================================   
  14. ALTER TRIGGER [dbo].[TR_TeachCourseLink_D]  
  15.       
  16.     ON [dbo].[TBR_TeachCourseLink]  
  17.   
  18.     INSTEAD OF DELETE  
  19. AS  
  20.       
  21.     DECLARE  
  22.     @err1 INT,                   --存储错误号   
  23.     @err2 INT,  
  24.     @err3 INT,  
  25.     @err4 INT,  
  26.     @err5 INT,  
  27.     @err6 INT,  
  28.     @err7 INT,  
  29.     @Indexing INT,               --授课课程主键   
  30.     @TeachClassID VARCHAR(36),           --虚拟班主键   
  31.     @StudentID VARCHAR(36)               --学生主键   
  32.   
  33. BEGIN  
  34.   
  35.     --选择要删除授课课程记录的主键   
  36.     SELECT @Indexing=Indexing FROM  <SPAN style="COLOR: #3333ff"><STRONG>deleted  --删除临时表</STRONG>   
  37. </SPAN>   
  38.     --开启事务   
  39.     BEGIN TRANSACTION  
  40.   
  41.         /*删除授课课程记录、授课课程与虚拟班关系、虚拟班   
  42.         字段为 “否”*/  
  43.   
  44.         --彻底删除授课课程记录   
  45.         DELETE TBR_TeachCourseLink  WHERE Indexing=@Indexing AND IsAvailable='否'  
  46.         SET @err1=@@ERROR  
  47.   
  48.         /*删除授课课程与选修课学生关系、学生表  
  49.         字段为 “否”*/  
  50.         --删除授课课程与选修课学生的关系表   
  51.         DELETE TBR_StuChooseCourseLink   WHERE Indexing=@Indexing and IsAvailable='否'  
  52.         SET @err6=@@ERROR  
  53.   
  54.         --删除学生表(需要触发多条记录,用游标操作)   
  55.         --声明游标   
  56.         DECLARE StudentCursor CURSOR FOR    
  57.         SELECT StudentID FROM TBR_StuChooseCourseLink  WHERE Indexing=@Indexing   
  58.         --打开游标   
  59.             OPEN StudentCursor  
  60.                     FETCH NEXT FROM StudentCursor INTO @StudentID  --给变量赋初始值   
  61.                     WHILE @@FETCH_STATUS=0 --语句执行成功   
  62.                     begin  
  63.                     --更新中的记录   
  64.                     DELETE TB_Student WHERE StudentID=@StudentID and  isAvailable = '否'   
  65.                     FETCH NEXT FROM StudentCursor INTO @StudentID  
  66.                     end  
  67.             --关闭并释放游标   
  68.             CLOSE StudentCursor  
  69.         DEALLOCATE StudentCursor  
  70.         SET @err7=@@ERROR  
  71.   
  72.     --判断是否执行成功   
  73.     IF (@err1 =0 and @err2=0 and @err3=0 and @err4=0 and @err5=0 and @err6=0 and @err7=0)  
  74.         --提交事务   
  75.         COMMIT TRANSACTION  
  76.     ELSE  
  77.         --事务回滚   
  78.         ROLLBACK TRANSACTION  
  79.   
  80.   
  81. END</SPAN>  


           触发器的工作原理以及什么时候使用两张临时表进行操作,可以用下面这张图表示:Inserted和Deleted两个临时表实现。

 

 

 

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多