【问题标题】:Trigger function updates all rows instead of one触发函数更新所有行而不是一个
【发布时间】:2020-09-07 18:01:56
【问题描述】:

我有表“orders”,我想在“tracking_code”列中添加值时自动更改“order_status”列(默认值为 null)但我的触发器函数更改了列“order_status”中的所有行我试图更改函数中的 if 语句,但没有成功。请帮我解决这个问题! 这是我的表“orders”:

id | order_status_id | tracking_code
----+-----------------+---------------
 12 |               2 | 123456
  9 |               2 |
  6 |               2 |
  7 |               2 |
 10 |               2 |
  8 |               2 |
 11 |               2 |

和表“order_statuses”:

 id |   status
----+-------------
  1 | QUEUE
  2 | IN_PROGRESS
  3 | IN_DELIVERY
  4 | DELIVERED
  5 | CANCELED
  6 | RETURNED

这是我的触发器函数

CREATE or REPLACE FUNCTION status_function() RETURNS VOID AS $$
BEGIN
    UPDATE public.orders SET order_status_id = public.order_statuses.id
    FROM public.order_statuses
    WHERE status = 'IN_DELIVERY';
END
$$ LANGUAGE plpgsql;

CREATE or REPLACE FUNCTION status_update() RETURNS TRIGGER AS $$
BEGIN
    IF (old.tracking_code != new.tracking_code) THEN
        PERFORM status_function();
        RETURN new;
    ELSE
        RETURN old;
    END IF;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER change_status
    AFTER UPDATE
        OF tracking_code
    ON orders
    FOR EACH ROW
EXECUTE PROCEDURE status_update();

【问题讨论】:

  • 您的status_function() 是对orders 的无条件更新。
  • 我知道status_function是我的错!但你能澄清你的答案吗?
  • 更新没有限制。它会将orders 中的所有行更新为order_status_id = 2

标签: sql database postgresql triggers


【解决方案1】:

请尝试这样的操作,将更新限制在当前行:

CREATE or REPLACE FUNCTION status_function(_id int) RETURNS VOID AS $$
BEGIN
    UPDATE public.orders SET order_status_id = public.order_statuses.id
      FROM public.order_statuses
     WHERE status = 'IN_DELIVERY'
       AND id = _id;
END
$$ LANGUAGE plpgsql;

CREATE or REPLACE FUNCTION status_update() RETURNS TRIGGER AS $$
BEGIN
    IF (old.tracking_code != new.tracking_code) THEN
        PERFORM status_function(old.id);
        RETURN new;
    ELSE
        RETURN old;
    END IF;
END;
$$ LANGUAGE plpgsql;

【讨论】:

    【解决方案2】:

    您需要将更新后的订单 id 传递给status_function

    CREATE or REPLACE FUNCTION status_function(bigint) RETURNS VOID AS $$
    BEGIN
        UPDATE public.orders SET order_status_id = public.order_statuses.id
        FROM public.order_statuses
        WHERE status = 'IN_DELIVERY' AND public.orders.id = $1;
    END
    $$ LANGUAGE plpgsql;
    

    然后,在status_update

    PERFORM status_function(old.id);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-21
      • 2017-10-28
      • 1970-01-01
      • 2012-08-29
      • 1970-01-01
      • 2021-09-08
      • 1970-01-01
      相关资源
      最近更新 更多