更新子表后数据库触发器更新父表上的行

Posted

技术标签:

【中文标题】更新子表后数据库触发器更新父表上的行【英文标题】:Database trigger to update a row on parent table after child table has been updated 【发布时间】:2015-05-12 02:46:22 【问题描述】:

第一次创建数据库触发器。我有一个子表,当其成本列更新时,我需要其父表也更新其成本列以反映更改。

到目前为止,这是我很抱歉的尝试。这显然行不通。我在弄清楚如何将总成本提取为变量并将其存储在父表中时遇到问题。

我目前的方法假设是静态的 id 值。我不完全确定如何动态确定更新行的 id 值。

CREATE TRIGGER ParentCost_Update
ON ChildTable
AFTER INSERT, UPDATE 

AS 
SELECT SUM(Cost) AS TotalCost FROM ChildTable where parent_id=2080

UPDATE ParentTable
    SET Cost=TotalCost
    where id=parent_id;

GO

当前脚本返回错误

消息 207,第 16 级,状态 1,过程 ParentCost_Update,第 9 行 列名“TotalCost”无效。

【问题讨论】:

【参考方案1】:

您需要小心触发器,因为可能会更新不止一行。因此,您需要进行基于行的处理。

要获取新插入/更新的行,请使用inserteddeleted 伪行。

几乎可以肯定,您还需要实现deleted 触发器,即,如果从子表中删除了需要重新计算父表的行。

这是一个基于行的镜头,使用 CTE 映射您上面的两步过程,如下所示:

CREATE TRIGGER ParentCost_Update
ON ChildTable
AFTER INSERT, UPDATE, DELETE
AS 
   SET NOCOUNT ON;
   WITH cteParentsAffected AS
   (
      SELECT ins.parent_id
      FROM inserted ins

      UNION

      SELECT del.parent_id
      FROM deleted del
   )
   , cteTotal AS
   (
      SELECT ct.parent_id, SUM(ct.Cost) AS TotalCost 
      FROM ChildTable ct
      INNER JOIN cteParentsAffected par
      ON ct.parent_id = par.parent_id
      GROUP BY ct.parent_id
   )
  UPDATE pt
      SET Cost=cte.TotalCost
      FROM ParentTable pt
      INNER JOIN cteTotal cte
      ON id=cte.parent_id;
GO

With a SqlFiddle here

【讨论】:

【参考方案2】:

试试这个

 Update parenttable set total= (select sum(total) from childtable c where c.id= parent table.id)
Where id in (select id from inserted)

更改表名和列名。

【讨论】:

以上是关于更新子表后数据库触发器更新父表上的行的主要内容,如果未能解决你的问题,请参考以下文章

通过在Oracle子表外键上建立索引提高性能

更新表上的触发器[关闭]

mysql数据库外键删除更新规则

创建一个触发器,当另一个表中的列更新时更新一个表上的列

插入更新另一个表后创建触发器

已解决 - ReactJS - 父表上的行选择崩溃嵌套表