我在表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,但我想不出一种不同的方式,或者是在触发器开始时捕获循环的最佳方法。
我正在考虑使用全局临时表并在触发器启动时检查插入的记录集,如果行已经存在于全局临时表中,则退出触发器。同事们向我保证,这可能会使问题过于复杂,或者两者都无效,或者存在更简单的答案?
非常感谢任何帮助。 托米
答案 0 :(得分:2)
由于您只引用了表格中的三个字段(wo_status
,wo_link_type
和wo_link
),我假设您只需在其中一个字段更新后触发此触发器。因此,更改触发器的update
部分,以便仅在更新这些特定字段时触发。由于您上次update
不会更改其中任何一项,因此将删除递归。
语法为for update of <field1>, <field2>, ...
。请参阅Oracle的documentation。
答案 1 :(得分:0)
在更新主表上导致初始触发的值之前,你不能“关闭”递归触发器吗?
我相信你可以。
看看在辅助触发器上这样做。