我在SQL Server 2008数据库的数据表上有下列触发程序。它是递归的,所以我必须停止它。
在插入或更新记录后,我尝试只更新该表中的单个字段。
这是触发器:
ALTER TRIGGER [dbo].[tblMediaAfterInsertOrUpdate]
ON [dbo].[tblMedia]
BEFORE INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON
DECLARE @IdMedia INTEGER,
@NewSubject NVARCHAR(200)
SELECT @IdMedia = IdMedia, @NewSubject = Title
FROM INSERTED
-- Now update the unique subject field.
-- NOTE: dbo.CreateUniqueSubject is my own function.
-- It just does some string manipulation.
UPDATE tblMedia
SET UniqueTitle = dbo.CreateUniqueSubject(@NewSubject) +
CAST((IdMedia) AS VARCHAR(10))
WHERE tblMedia.IdMedia = @IdMedia
END
谁能告诉我如何防止扳机的插入物再次触发另一个扳机?
7条答案
按热度按时间qojgxg4l1#
不确定它是否与OP的问题相关,但是如果你来这里是为了找出如何防止递归或相互递归在触发器中发生,你可以这样测试:
MSDN第一版
ryhaxcpt2#
我看到三种可能性:
1.禁用触发器递归:
这将防止触发器调用另一个触发器或再次调用自身。为此,请执行以下命令:
1.使用触发器代替UPDATE、INSERT
使用
INSTEAD OF
触发器,您可以控制任何正在更新/插入的列,甚至可以在调用命令之前进行替换。1.通过防止使用IF UPDATE来控制触发器
测试数据行会以合理的精确度告诉您触发程序是否正在呼叫本身。若要这麽做,请使用
IF UPDATE()
子句,例如:sdnqo3pr3#
TRIGGER_NESTLEVEL
可用于防止特定触发器的递归,但将触发器的对象ID传递到函数中很重要。否则,当另一个触发器执行插入或更新操作时,您也会阻止触发器触发:从MSDN开始:
未指定参数时,TRIGGER_NESTLEVEL会传回堆栈回退上的触发程序总数。这包括它本身。
参考:Avoiding recursive triggers
ekqde3dh4#
RECURSIVE_TRIGGERS { ON | OFF }
ON允许递归引发AFTER触发程序。
OFF只允许直接递归引发AFTER触发程序。若要同时停用AFTER触发程序的间接递归,请使用sp_configure将巢状触发程序服务器选项设定为0。
当RECURSIVE_TRIGGERS设置为OFF时,只禁止直接递归。若要禁用间接递归,还必须将嵌套触发器服务器选项设置为0。
这个选项的状态可以借由检查sys.databases目录检视中的is_recursive_triggers_on数据行或ASEPROPERTYEX函数的IsRecursiveTriggersEnabled属性来判断。
cnwbcb6i5#
我 想 我 明白 了 : )
当 标题 被 " 更新 " 时 ( 阅读 :当 触发 器 第 二 次 运行 时 , uniquessubject 字段 被 更新 , 因此 它 停止 并 离开 触发 器 。
此外 , 我 已经 使 它 处理 多 行 被 更改 - 〉 我 总是 忘记 这 与 触发 器 。
中 的 每 一 个
eit6fx6z6#
您可以使用单独的NULLABLE列来指示是否设置了UniqueTitle。
在触发器中将其设置为true值,如果在“INSERTED”中其值为true,则触发器不执行任何操作
bqjvbblv7#
如果您有一个特定的after触发器,并且只想运行一次,那么可以使用sp_settriggerorder将其设置为最后运行。
我还会考虑将执行递归的触发器合并为一个触发器是否是最好的做法。