【问题标题】:Count sum with trigger for delete/update/insert使用删除/更新/插入触发器计算总和
【发布时间】:2022-01-15 19:00:28
【问题描述】:

我想创建连续更新价格的触发器。但是,每当我添加金额时,这都可以正常工作,但每当我删除项目或以较小的值更新时,它就不起作用。如何使此触发器满足所有 3 个需求?我不想编写多个触发器来处理这个问题。

CREATE FUNCTION sum_total() RETURNS TRIGGER
AS $$
BEGIN
    UPDATE payment
    SET price = price + (SELECT SUM(price) from basket WHERE service_id = new.service_id)
    WHERE service_id = new.service_id;
    RETURN NULL;
END; $$ LANGUAGE plpgsql;

CREATE TRIGGER sum_total AFTER INSERT ON basket
    FOR EACH ROW EXECUTE PROCEDURE sum_total();

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    Postgres 触发器函数有一组可用的special local variables。其中之一,TG_OP 表示导致触发器触发的操作。有了这个,multiple 的基本模板就变成了:

    create function trigger_function_name() 
      returns trigger
      language plpgsql
    as $$
    begin
        case TG_OP
             when 'INSERT'   then  
                  <place code for insert processing here>
             when 'UPDATE'   then 
                  <place code for update processing here>         
             when 'DELETE'   then
                  <place code for delete processing here>         
             when 'TRUNCATE' then 
                  <place code for truncate processing here>   -- note must be Statement level trigger        
        end ; 
        return new; 
    end ; 
    $$ ; 
    

    但是,我建议不要尝试这样做。快速保持运行总计变得复杂。尤其是当您尝试维护的价值很容易交付时:

    select sum(price) from basket where service_id = service_id_parameter;

    这又带来了一点。您计算 payment 的算法存在根本缺陷,无法正常工作。考虑一个用户,他以 10 的价格在他们的购物篮中添加了一个项目。付款价格不会是 10(如果这是第一个项目会发生什么?payment 条目是否存在于那个 service_id?)现在在稍后,该用户添加了第二个项目,例如 20。现在 basket 中的总数现在是 30 (10+20),但 payment 中的值是 40 (10 + sum(10,20))。另一个拥有相同项目但以相反顺序选择它们的用户会发生什么。 (提示,您将获得不同的 payment 值。)
    最佳流程: 除非您期望有数百万人,否则只需完全消除触发器并在需要时导出 payment,也许使用这样做的视图。

    【讨论】:

      【解决方案2】:

      您可以使用OR 指定不同的事件类型 来自文档: https://www.postgresql.org/docs/9.2/sql-createtrigger.html

      event
      One of INSERT, UPDATE, DELETE, or TRUNCATE; this specifies the 
      event that will fire the trigger.
      Multiple events can be specified using OR.
      

      【讨论】:

      • 我知道。但是当我删除触发器时不会删除总和。
      猜你喜欢
      • 1970-01-01
      • 2011-02-27
      • 2011-05-05
      • 2011-01-15
      • 2015-04-26
      • 1970-01-01
      • 2012-09-19
      • 2011-11-25
      • 2020-09-09
      相关资源
      最近更新 更多