我尝试优化我的一些处理。我有两个表(Job 和 Bucket),它们都具有我想要同步的状态。即如果有人更改了作业的状态,那么有时我会更改存储桶的状态,有时当我更改存储桶的状态时,我想更改附加作业的状态。有时在这方面主要意味着“取消”,但也意味着从作业流向存储桶的完成/错误。
它们有 2 个状态的原因是(a)它们是独立的子系统,例如可以暂停作业,以及(b)并非每个作业都附加到存储桶;)
我尝试使用 2 个触发器来执行此操作 - 一个在作业上更新,一个在存储桶上更新,但似乎每当作业上的触发器更改存储桶时,存储桶上的触发器就会触发。好笑的是,虽然这是一个更新后的触发器,但似乎触发器并没有看到另一个表中的变化......这导致了递归。
触发器是:
ALTER TRIGGER [grd].[Job_UpdateBucket]
ON [grd].[Job]
AFTER UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
UPDATE
[simstg].[Bucket]
SET
[Status] = i.[Status],
[StatusTimestamp] = GETUTCDATE()
FROM
[simstg].[Bucket] b
JOIN [inserted] i ON (b.[JobRef] = i.[Id])
WHERE
i.[Status] IN ('C', 'F', 'X', 'A')
AND b.[Status] <> i.[Status]
AND b.[Status] NOT IN ('X')
END
和
ALTER TRIGGER [simstg].[Bucket_UpdateJob]
ON [simstg].[Bucket]
AFTER UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
UPDATE
[grd].[Job]
SET
[Status] = 'X',
[LastUpdate] = GETUTCDATE()
FROM
[grd].[Job] j
JOIN [inserted] i ON (j.Id = i.JobRef)
WHERE
i.[Status] = 'X'
AND j.[Status] <> i.[Status]
END
这是 - 虽然我做 SQL 很长时间 - 我第一次有这种类型或递归。我认为where条件可以避免递归,因为它是一个AFTER触发器,所以如果Job更新bucket,bucket触发器应该看到job中已经改变的状态,所以应该没有递归。
这导致两个问题:
1:我错了吗?如果我更新 Job,那么触发器会更改 Bucket,那么 Bucket 上的触发器应该会看到 Job 中更改的数据,还是?由于比较状态与新状态不同的 WHERE 条件,这应该可以避免递归。
2:这里有什么其他方法可以避免递归吗?