无限循环触发器

时间:2009-11-27 17:05:36

标签: sql tsql loops triggers

我在表x上有一个更新/插入触发器。在此触发器中,我需要检查某个列是否已更新,这对于删除/插入的表比较来说非常简单。但是,如果某个列已更改为某个值,我需要更新表x中的插入行。这样做显然会创建一个循环。问题是我没有任何运气在触发器开始时捕获循环。

我正在使用的SQL在下面,为可怕的临时表名称道歉。

FOR INSERT, UPDATE
AS 
BEGIN

SELECT  i1.wo_id,
        i1.wo_status,
        i1.wo_link_type,
        i1.wo_link 
INTO    #x_MLN16901 
FROM    inserted AS i1
WHERE   i1.wo_status = 7

DELETE 
FROM    #x_MLN16901 
WHERE   #x_MLN16901.wo_id IN
            (
            SELECT  d1.wo_id
            FROM    deleted AS d1
            WHERE   d1.wo_status <> 7 OR
                    d1.wo_link_type <> 'PM'
            ) OR
        #x_MLN16901.wo_id IN
            (
            SELECT  i2.wo_id
            FROM    inserted AS i2
            WHERE   i2.wo_link_type <> 'PM'
            )


IF  (SELECT COUNT(*) FROM #x_MLN16901) = 0
    RETURN

UPDATE  workorders
SET     workorders.wo_action_date = GETDATE()
WHERE   workorders.wo_id IN
            (
            SELECT  wo_id
            FROM    #x_MLN16901
            )

我理解这最后一个更新语句是cuplrit,但我想不出一种不同的方式,或者是在触发器开始时捕获循环的最佳方法。

我正在考虑使用全局临时表并在触发器启动时检查插入的记录集,如果行已经存在于全局临时表中,则退出触发器。同事们向我保证,这可能会使问题过于复杂,或者两者都无效,或者存在更简单的答案?

非常感谢任何帮助。 托米

2 个答案:

答案 0 :(得分:2)

由于您只引用了表格中的三个字段(wo_statuswo_link_typewo_link),我假设您只需在其中一个字段更新后触发此触发器。因此,更改触发器的update部分,以便仅在更新这些特定字段时触发。由于您上次update不会更改其中任何一项,因此将删除递归。

语法为for update of <field1>, <field2>, ...。请参阅Oracle的documentation

答案 1 :(得分:0)

在更新主表上导致初始触发的值之前,你不能“关闭”递归触发器吗?

我相信你可以。

看看在辅助触发器上这样做。