如何控制触发器递归

原创 2007年08月05日 03:06:00
 
背景
AUPDATE后,取B表某列再次UPDATE A表,这样又触发了A表的 UPDATE  触发器,我的目的是只触发一次,是否设置 nested triggers 选项关闭递归触发器即可?
分析
首先,必须清楚触发器递归的定义,触发器有两种递归方式:
1.     直接递归
A表上的触发器更改(插入/删除/更新)A表数据,导致A表的触发器再次触发,这种状况称之为直接递归;
2.     间接递归
A表上的触发器更新B表数据,导致触发B表触发器;而B表触发器又更改A表数据,导致A表触发器再次触发,这种状况称之为间接递归
解决方法选项配置(影响所有范围的触发器)
SQL Server提供了数据库级和服务器级配置来确定递归触发器是否被允许:
1.       服务器级(使用存储过程sp_configure 进行配置)
server trigger recursion 选项(SQL Server 2005)决定是否允许服务器级触发器直接递归激发;当此选项设置为1 (ON,默认值)时,将允许服务器级触发器递归激发;当设置为0 (OFF) 时,服务器级触发器不能递归激发。
nested triggers选项决定是否允许触发器间接递归激发;当此选项设置为1 (ON,默认值)时,将允许触发器递归激发;当设置为0 (OFF) 时,触发器不能递归激发。
2.       数据库级
RECURSIVE_TRIGGERS数据库选项设置决定是否允许数据库中的触发器直接递归触发;默认值为OFF,不允许直接递归触发。
该选项可以通过存储过程sp_dboption设置;对于SQL Server 2005,还可以使用类似下面的T-SQL设置:
ALTER DATABASE [DbName]
    SET RECURSIVE_TRIGGERS ON
使用选项决定递归触发器的行为时,需要注意的是选项设置的有效范围:
nested triggers选项决定所有的触发器是否间接递归激发,这意味着这是一个SQL Server实例级的选项,设置将影响所有的触发器。
server trigger recursion选项是SQL Server 2005中才有的(SQL Server 2005才有服务器级触发器)。
RECURSIVE_TRIGGERS选项影响配置它的数据库中的所有触发器。
其他解决方法(针对特定的触发器)
如果只希望特定的触发器允许或者禁止触发器,则SQL Server没有选项可以做到;如果确实需要这样的功能,可以在触发器代码中实现控制:
1.       使用update(列名)函数
此函数适用于对 UPDATE 的控制。对于"AUPDATE 后,取B表某列再次UPDATE A",如果仅更新A表的某些列才触发UPDATE B, 并且B 表再次UPDATE A表不会包含A表触发UPDATE B的那些列,则在A表的触发器中,使用IF UPDATE()来确定是否应该UPDATE B即可。
2.       使用@@NESTLEVEL
该变量值确定嵌套层数。
对于"Aupdate后,取B表某列再次UPDATE A",如果触发者不是一个存储过程, UPDATE A A表触发器@@NESTLEVEL = 1, UPDATE B, B表触发器 @@NESTLEVEL = 2, B表触发器再UPDATE A, @@NESTLEVEL = 3
所以如果 @@NESTLEVEL >=3 , 一般表示递归了(当然, 前提是UPDATE A的触发器本身没有两层的递归, 即不能是存储过程再调用存储过程去UPDATE A
3.       使用 @@PROCID
该全局变量返回调用者的object_id如果需要A表触发B表触发器,而B表触发器再触发A表触发器时,A表触发器不响应;则在A表触发器中使用它来判断触发者是谁,如果是B表触发器,则不处理就行了,类似下面这样
IF OBJECT_ID(N'B表触发器名称') = @@PROCID
BEGIN
    PRINT 'B表触发器, 不处理'
    RETURN
END
 

5.SQL Server DML触发器--嵌套和递归触发器

 本文摘自《锋利的SQL》:http://item.jd.com/10380652.html 1.嵌套触发器 无论是DML触发器还是DDL触发器,如果出现了一个触发器执行启动另一个触...
  • zhanghongju
  • zhanghongju
  • 2014年01月16日 21:06
  • 2979

sql 触发器 直接递归触发器

  create trigger [dbo].[loving20000]on [dbo].[s]for deleteas declare @age int  select @age = sage fr...
  • wwttqq85538649
  • wwttqq85538649
  • 2010年12月16日 15:52
  • 368

触发器递归的定义SQL

背景 A表UPDATE后,取B表某列再次UPDATE A表,这样又触发了A表的 UPDATE  触发器,我的目的是只触发一次,是否设置nested triggers 选项关闭递归触发器即可? 分析...
  • mfkpie
  • mfkpie
  • 2014年06月12日 20:36
  • 669

ORACLE触发器详解

ORACLE PL/SQL编程之八:  把触发器说透    本篇主要内容如下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创...
  • IndexMan
  • IndexMan
  • 2012年09月27日 10:00
  • 375057

前触发器和后触发器简介(downmoon)

前触发器和后触发器简介    触发器是一种特殊的存储过程。当Insert Update 或者Delete 语句修改表中一个或者多个行时执行触发器。因为SQL Server 对特定表上的每一个指定操作调...
  • downmoon
  • downmoon
  • 2006年04月06日 15:31
  • 5950

【触发器】数据库_触发器实例

数据库触发器案例 一、课堂演示案例 例一:创建一个简单的insert触发器 先创建一个数据库备用 create database sampledb go   use sampledb ...
  • moshenglv
  • moshenglv
  • 2016年07月31日 15:31
  • 2336

MySQL触发器Trigger实例篇

MySQL触发器Trigger实例篇 发表于668 天前 ⁄ IT技术 ⁄ 暂无评论 以前关注的数据存储过程不太懂其中奥妙,最近遇到跨数据库,同时对多个表进行CURD(Create...
  • hireboy
  • hireboy
  • 2014年01月10日 11:45
  • 29247

各类触发器

1.触发器能够存储一位2值信号的基本单元电路叫做触发器2.SR锁存器(直接置位复位锁存器Set-Reset Latch)由输入引脚直接决定保持状态,不需要触发信号的触发。由2个或非门电路组成,或由两个...
  • Augusdi
  • Augusdi
  • 2013年12月06日 22:45
  • 3787

如何控制触发器递归

 背景A表UPDATE后,取B表某列再次UPDATE A表,这样又触发了A表的 UPDATE  触发器,我的目的是只触发一次,是否设置 nested triggers 选项关闭递归触发器即可?分析首先...
  • zjcxc
  • zjcxc
  • 2007年08月05日 03:06
  • 9451

触发器同步数据针对表,这样的主要是针对个别表同步技术使用

此原理 就是使用的触发器做的 同步操作 同步 个别数据使用, 主要是用于 帐号注册  这些。 根据实际情况选择使用 *--同步两个数据库的示例 有数据 srv1.库名..author...
  • tanym530
  • tanym530
  • 2015年09月08日 10:00
  • 138
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:如何控制触发器递归
举报原因:
原因补充:

(最多只允许输入30个字)