【问题标题】: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”无效。

【问题讨论】:

    标签: sql sql-server triggers database-trigger


    【解决方案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)
      

      更改表名和列名。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多