【问题标题】:After Update Trigger to Maintain Badge Count更新触发器以保持徽章计数后
【发布时间】:2021-06-22 17:23:32
【问题描述】:

我想知道如何使用我创建的表上的触发器来完成某些事情?

我有以下表格: 客户账户 客户端活动

在 ClientAccount 我有一个属性,它是一个客户端拥有的 ClientActivity 记录数的计数。我使用该计数作为选项卡上的徽章。

每当创建新活动时,都会触发以下触发器:

SELECT ALL

USE [officemgt]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER [dbo].[RecountInsertedClientActivities] 
   ON  [dbo].[CLIENTACTIVITY]
   AFTER INSERT 
AS 
BEGIN

    SET NOCOUNT ON;

    UPDATE CLIENTACCOUNT
    SET Count_ClientActivitiesAsClient=(SELECT COUNT(*) FROM ClientActivity WHERE ClientActivity.parent_Client_RID=CLIENTACCOUNT.ID)
    FROM inserted
    LEFT JOIN CLIENTACCOUNT ON CLIENTACCOUNT.ID=inserted.parent_Client_RID

END

如果 ClientActivity 记录被删除,我会触发类似的触发器。

这两个触发器工作得很好。

问题在于,有时活动可能会从一个客户端更改为另一个客户端。因此,我需要更新旧客户端的计数以减少计数,然后更新分配活动的新客户端的计数。

我该怎么做?

【问题讨论】:

  • 创建一个更新后触发器,然后做你现在正在做的事情?
  • 在此处查看参考资料docs.microsoft.com/en-us/sql/relational-databases/triggers/…。只是为了让您完全理解,触发器中的“已删除”表不仅存在于 DELETE 触发器中 - 它也存在于 UPDATE 触发器中,并且在这种情况下它将保存更新前的值(因此 Dale 的答案有效,因为“已删除”表中的客户端 ID 是更改前的值)
  • 我注意到您没有接受您提出的单个问题的答案。在本网站上,您要么接受最有帮助的答案或,您就可以评论为什么该答案不能解决您的问题。我鼓励您重新审视您的问题并奖励一些答案。
  • 另见stackoverflow.com/questions/65778999/…,它显示了基于索引视图的类似问题的更好解决方案,无需触发器
  • 何必呢?可以将视图定义为“虚拟”执行此操作,而无需复杂的触发代码,并且视图将始终正确。

标签: sql sql-server tsql triggers


【解决方案1】:

您可以编写一个单个触发器来处理插入、更新和删除,如下所示:

ALTER TRIGGER [dbo].[RecountInsertedClientActivities] 
   ON  [dbo].[CLIENTACTIVITY]
   AFTER INSERT, UPDATE, DELETE
AS 
BEGIN
    SET NOCOUNT ON;

    UPDATE CA SET
        Count_ClientActivitiesAsClient = (SELECT COUNT(*) FROM dbo.ClientActivity CV WHERE CV.parent_Client_RID = CA.ID)
    FROM dbo.CLIENTACCOUNT CA
    WHERE CA.ID in (SELECT I.parent_Client_RID FROM INSERTED I UNION ALL SELECT D.parent_Client_RID FROM DELETED D);
END;

【讨论】:

  • 感谢 Dale,我实际上想知道是否可以在一个触发器中完成所有操作。我最喜欢那个解决方案。
【解决方案2】:

您可以使用deleted 表。 inserted 包含所有新记录,deleted 包含更新/删除触发器中的所有记录:

  UPDATE CLIENTACCOUNT
    SET Count_ClientActivitiesAsClient=(SELECT COUNT(*) FROM ClientActivity WHERE ClientActivity.parent_Client_RID=CLIENTACCOUNT.ID)
    FROM inserted
    LEFT JOIN CLIENTACCOUNT ON CLIENTACCOUNT.ID=inserted.parent_Client_RID


  UPDATE CLIENTACCOUNT
    SET Count_ClientActivitiesAsClient=(SELECT COUNT(*) FROM ClientActivity WHERE ClientActivity.parent_Client_RID=CLIENTACCOUNT.ID)
    FROM deleted
    LEFT JOIN CLIENTACCOUNT ON CLIENTACCOUNT.ID=deleted.parent_Client_RID

【讨论】:

  • 您可能需要提到需要创建一个“更新”触发器。
  • 触发器中的实际表名是“deleted”和“inserted”
猜你喜欢
  • 2015-07-02
  • 2013-09-29
  • 2015-12-04
  • 1970-01-01
  • 2012-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多