5-8万年薪顶级嵌入式,京沪深就业地 浅谈并行编程中的任务分解模式
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  MS-SQL Server >  非技术版

有关TRIGGER递归调用得问题

楼主libtiny(li biao)2002-01-11 13:53:23 在 MS-SQL Server / 非技术版 提问

我有两个相同表A   ,B分别在两个数据库中,为了保证两表内容相同,我在两表上都创建了TRIGGER。我没有把数据库的   recursive   triggers   设置为ON,   但同样可以。  
  在MSSQL帮助中:  
  Recursive   Triggers  
   
  SQL   Server   also   allows   recursive   invocation   of   triggers   when   the   recursive   triggers   setting   is   enabled   in   sp_dboption.  
  Recursive   triggers   allow   two   types   of   recursion   to   occur:  
   
  ?Indirect   recursion  
  ?Direct   recursion  
   
  With   indirect   recursion,   an   application   updates   table   T1,   which   fires   trigger   TR1,   updating   table   T2.   In   this   scenario,   trigger   T2   then   fires   and   updates   table   T1.  
  With   direct   recursion,   the   application   updates   table   T1,   which   fires   trigger   TR1,   updating   table   T1.   Because   table   T1   has   been   updated,   trigger   TR1   fires   again,   and   so   on.  
  This   example   uses   both   indirect   and   direct   trigger   recursion.   Assume   that   two   update   triggers,   TR1   and   TR2,   are   defined   on   table   T1.   Trigger   TR1   updates   table   T1   recursively.   An   UPDATE   statement   executes   each   TR1   and   TR2   one   time.   In   addition,   the   execution   of   TR1   triggers   the   execution   of   TR1   (recursively)   and   TR2.   The   inserted   and   deleted   tables   for   a   given   trigger   contain   rows   corresponding   only   to   the   UPDATE   statement   that   invoked   the   trigger.  
   
  Note     The   above   behavior   occurs   only   if   the   recursive   triggers   setting   of   sp_dboption   is   enabled.   There   is   no   defined   order   in   which   multiple   triggers   defined   for   a   given   event   are   executed.   Each   trigger   should   be   self-contained.  
   
  最后一段好像说要设置recursive   triggers,不太明白,谁能讲清楚一下MSSQL的TRIGGER中递归的问题?谢谢。  
   
   
  问题点数:0、回复次数:3Top

1 楼net_steven(素狼(W))回复于 2002-01-11 20:23:00 得分 0

如果e文困难给一段中文看看:  
  -------------------------------------------------------------  
  递归触发器  
  当在   sp_dboption   中启用   recursive   triggers   设置时,SQL   Server   还允许触发器的递归调用。  
   
  递归触发器允许发生两种类型的递归:    
   
  间接递归  
   
   
  直接递归    
  使用间接递归时,应用程序更新表   T1,从而激发触发器   TR1,该触发器更新表   T2。在这种情况下,触发器   T2   将激发并更新   T1。  
   
  使用直接递归时,应用程序更新表   T1,从而激发触发器   TR1,该触发器更新表   T1。由于表   T1   被更新,触发器   TR1   再次激发,依此类推。  
   
  下例既使用了间接触发器递归,又使用了直接触发器递归。假定在表   T1   中定义了两个更新触发器   TR1   和   TR2。触发器   TR1   递归地更新表   T1。UPDATE   语句使   TR1   和   TR2   各执行一次。而   TR1   的执行将触发   TR1(递归)和   TR2   的执行。给定触发器的   inserted   和   deleted   表只包含与唤醒调用触发器的   UPDATE   语句相对应的行。  
   
   
   
  说明     只有启用   sp_dboption   的   recursive   triggers   设置,才会发生上述行为。对于为给定事件定义的多个触发器,并没有确定的执行顺序。每个触发器都应是自包含的。  
   
   
  禁用   recursive   triggers   设置只能禁止直接递归。若要也禁用间接递归,请使用   sp_configure   将   nested   triggers   服务器选项设置为   0。  
   
  如果任一触发器执行了   ROLLBACK   TRANSACTION   语句,则无论嵌套级是多少,都不会进一步执行其它触发器。  
   
  嵌套触发器  
  触发器最多可以嵌套   32   层。如果一个触发器更改了包含另一个触发器的表,则第二个触发器将激活,然后该触发器可以再调用第三个触发器,依此类推。如果链中任意一个触发器引发了无限循环,则会超出嵌套级限制,从而导致取消触发器。若要禁用嵌套触发器,请用   sp_configure   将   nested   triggers   选项设置为   0(关闭)。默认配置允许嵌套触发器。如果嵌套触发器是关闭的,则也将禁用递归触发器,与   sp_dboption   的   recursive   triggers   设置无关。  
   
  Top

2 楼rwq_(笨笨@天外有天山外有山)回复于 2002-01-11 22:25:56 得分 0

我靠,以前我看一本书说什么TRIGGER的最多嵌套层次最多只有16层!误人子弟!Top

3 楼rwq_(笨笨@天外有天山外有山)回复于 2002-01-11 22:28:55 得分 0

我干脆把一段更为完整的拉上去吧!(来自SQL2000下面的帮助):  
  ================================================================================  
  使用嵌套触发器  
  如果一个触发器在执行操作时引发了另一个触发器,而这个触发器又接着引发下一个触发器……这些触发器就是嵌套触发器。触发器可嵌套至   32   层,并且可以控制是否可以通过"嵌套触发器"服务器配置选项进行触发器嵌套。  
   
  如果允许使用嵌套触发器,且链中的一个触发器开始一个无限循环,则超出嵌套级,而且触发器将终止。  
   
  可使用嵌套触发器执行一些有用的日常工作,如保存前一触发器所影响行的一个备份。例如,可以在   titleauthor   上创建一个触发器,以保存由   delcascadetrig   触发器所删除的   titleauthor   行的备份。在使用   delcascadetrig   时,从   titles   中删除title_id   PS2091   将删除   titleauthor   中相应的一行或多行。要保存数据,可在   titleauthor   上创建   DELETE   触发器,该触发器的作用是将被删除的数据保存到另一个单独创建的名为   del_save   表中。例如:  
   
  CREATE   TRIGGER   savedel  
        ON   titleauthor  
  FOR   DELETE  
  AS  
        INSERT   del_save  
        SELECT   *   FROM   deleted  
   
  不推荐按依赖于顺序的序列使用嵌套触发器。应使用单独的触发器层叠数据修改。  
   
   
   
  说明     由于触发器在事务中执行,如果在一系列嵌套触发器的任意层中发生错误,则整个事务都将取消,且所有的数据修改都将回滚。在触发器中包含   PRINT   语句,用以确定错误发生的位置。  
   
   
  递归触发器  
  触发器不会以递归方式自行调用,除非设置了   RECURSIVE_TRIGGERS   数据库选项。有两种不同的递归方式:    
   
  直接递归    
  即触发器激发并执行一个操作,而该操作又使同一个触发器再次激发。例如,一应用程序更新了表   T3,从而引发触发器   Trig3。Trig3   再次更新表   T3,使触发器   Trig3   再次被引发。  
   
  间接递归    
  即触发器激发并执行一个操作,而该操作又使另一个表中的某个触发器激发。第二个触发器使原始表得到更新,从而再次引发第一个触发器。例如,一应用程序更新了表   T1,并引发触发器   Trig1。Trig1   更新表   T2,从而使触发器   Trig2   被引发。Trig2   转而更新表   T1,从而使   Trig1   再次被引发。  
   
  当将   RECURSIVE_TRIGGERS   数据库选项设置为   OFF   时,仅防止直接递归。若要也禁用间接递归,请将   nested   triggers   服务器选项设置为   0。  
   
  示例  
  A.   使用递归触发器解决自引用关系  
  递归触发器的一种用法是用于带有自引用关系的表(亦称为传递闭包)。例如,表   emp_mgr   定义了:    
   
  一个公司的雇员   (emp)。  
   
   
  每个雇员的经理   (mgr)。  
   
   
  组织树中向每个经理汇报的雇员总数   (NoOfReports)。    
  递归   UPDATE   触发器在插入新雇员记录的情况下可以使   NoOfReports   列保持最新。INSERT   触发器更新经理记录的   NoOfReports   列,而该操作递归更新管理层向上其它记录的   NoOfReports   列。  
   
  USE   pubs  
  GO  
  --   Turn   recursive   triggers   ON   in   the   database.  
  ALTER   DATABASE   pubs  
        SET   RECURSIVE_TRIGGERS   ON  
  GO  
  CREATE   TABLE   emp_mgr   (  
        emp   char(30)   PRIMARY   KEY,  
          mgr   char(30)   NULL   FOREIGN   KEY   REFERENCES   emp_mgr(emp),  
          NoOfReports   int   DEFAULT   0  
  )  
  GO  
  CREATE   TRIGGER   emp_mgrins   ON   emp_mgr  
  FOR   INSERT  
  AS  
  DECLARE   @e   char(30),   @m   char(30)  
  DECLARE   c1   CURSOR   FOR  
        SELECT   emp_mgr.emp  
        FROM       emp_mgr,   inserted  
        WHERE   emp_mgr.emp   =   inserted.mgr  
   
  OPEN   c1  
  FETCH   NEXT   FROM   c1   INTO   @e  
  WHILE   @@fetch_status   =   0  
  BEGIN  
        UPDATE   emp_mgr  
        SET   emp_mgr.NoOfReports   =   emp_mgr.NoOfReports   +   1   --   Add   1   for   newly  
        WHERE   emp_mgr.emp   =   @e                                                         --   added   employee.  
   
        FETCH   NEXT   FROM   c1   INTO   @e  
  END  
  CLOSE   c1  
  DEALLOCATE   c1  
  GO  
  --   This   recursive   UPDATE   trigger   works   assuming:  
  --       1.   Only   singleton   updates   on   emp_mgr.  
  --       2.   No   inserts   in   the   middle   of   the   org   tree.  
  CREATE   TRIGGER   emp_mgrupd   ON   emp_mgr   FOR   UPDATE  
  AS  
  IF   UPDATE   (mgr)  
  BEGIN  
        UPDATE   emp_mgr  
        SET   emp_mgr.NoOfReports   =   emp_mgr.NoOfReports   +   1   --   Increment   mgr's  
        FROM   inserted                                                         --   (no.   of   reports)   by  
        WHERE   emp_mgr.emp   =   inserted.mgr                   --   1   for   the   new   report.  
   
        UPDATE   emp_mgr  
        SET   emp_mgr.NoOfReports   =   emp_mgr.NoOfReports   -   1   --   Decrement   mgr's  
        FROM   deleted                                                           --   (no.   of   reports)   by   1  
        WHERE   emp_mgr.emp   =   deleted.mgr                     --   for   the   new   report.  
  END  
  GO  
  --   Insert   some   test   data   rows.  
  INSERT   emp_mgr(emp,   mgr)   VALUES   ('Harry',   NULL)  
  INSERT   emp_mgr(emp,   mgr)   VALUES   ('Alice',   'Harry')  
  INSERT   emp_mgr(emp,   mgr)   VALUES   ('Paul',   'Alice')  
  INSERT   emp_mgr(emp,   mgr)   VALUES   ('Joe',   'Alice')  
  INSERT   emp_mgr(emp,   mgr)   VALUES   ('Dave',   'Joe')  
  GO  
  SELECT   *   FROM   emp_mgr  
  GO  
  --   Change   Dave's   manager   from   Joe   to   Harry  
  UPDATE   emp_mgr   SET   mgr   =   'Harry'  
  WHERE   emp   =   'Dave'  
  GO  
  SELECT   *   FROM   emp_mgr  
  GO  
   
  以下是更新前的结果:  
   
  emp                                                         mgr                                                       NoOfReports  
  ------------------------------   -----------------------------   -----------  
  Alice                                                     Harry                                                     2  
  Dave                                                       Joe                                                         0  
  Harry                                                     NULL                                                       1  
  Joe                                                         Alice                                                     1  
  Paul                                                       Alice                                                     0  
   
  以下为更新后的结果:  
   
  emp                                                         mgr                                                       NoOfReports  
  ------------------------------   -----------------------------   -----------  
  Alice                                                     Harry                                                     2  
  Dave                                                       Harry                                                     0  
  Harry                                                     NULL                                                       2  
  Joe                                                         Alice                                                     0  
  Paul                                                       Alice                                                     0  
   
  Top

相关问题

  • 递归调用
  • 递归调用!
  • 递归调用?
  • 有关递归调用的地址传递的问题
  • 递归调用的问题
  • 递归调用游标?
  • 有关递归
  • VB的递归调用有几层啊?
  • 关于递归调用问题
  • vb递归调用益处的问题

关键词

  • 执行
  • 选项
  • 语句
  • 触发器
  • 递归
  • mgr
  • 嵌套
  • noofreports
  • emp
  • trigger

得分解答快速导航

  • 帖主:libtiny

相关链接

  • SQL Server类图书

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
x 提问