如何在 Postgres 中触发更新后

How to trigger AFTER UPDATE in Postgres

我正在尝试 运行 当 table 更新时 procedure/function (insert/delete/update),但是,该函数似乎没有得到 运行 当触发器发生或触发器未在插入时被触发。

函数和触发器:

CREATE OR REPLACE FUNCTION fn_rental_trigger() RETURNS TRIGGER AS $$
   BEGIN
    CALL get_top_ten_rentals();
    RETURN NULL;
   END; $$
LANGUAGE plpgsql;

CREATE TRIGGER tr_new_rentals
    AFTER UPDATE ON public.rental
    EXECUTE FUNCTION public.fn_rental_trigger();

插入调用:

INSERT INTO public.rental (rental_date, inventory_id, customer_id, return_date, staff_id, last_update)
VALUES (NOW(), 4030, 459, NOW() + interval '7 day', 1, NOW());

存储过程按预期工作,当我 运行 它单独运行时,我得到了我想要的。 运行 我尝试的每一种方法都失败了,那么 运行 一个在 table 更新上执行工作程序的触发器的正确​​方法是什么?

对于上下文,这是基于来自 postgres tutorial website 的 dvd 租赁数据库。


编辑

存储过程:

CREATE OR REPLACE PROCEDURE get_top_ten_rentals()

AS
$$

-- Start a tansaction to get the data
BEGIN
    
    -- clear out existing data to refresh list
    DELETE FROM report.top_ten_rentals;

    INSERT INTO report.top_ten_rentals (title, inventory_id, rating, length, times_rented, total)
    SELECT f.title AS title,
           r.inventory_id AS inventory_id,
           f.rating,
           fn_transform_length(f.length),
           COUNT(*) AS times_rented,
           SUM(p.amount) AS total
    FROM public.payment AS p
        JOIN public.rental AS r ON p.rental_id = r.rental_id
        JOIN public.inventory AS i ON r.inventory_id = i.inventory_id
        JOIN public.film AS f ON i.film_id = f.film_id
    GROUP BY r.inventory_id, f.title, f.rating, f.length
    ORDER BY total DESC
    LIMIT 10;

    -- Rollback when there is an exception to preserve data integrity
    EXCEPTION
        WHEN OTHERS THEN
            ROLLBACK;
END;
$$

LANGUAGE plpgsql;

回答 Adrian Klaver 的其他问题:


我也尝试过 运行 触发器:

CREATE TRIGGER tr_new_rentals
    AFTER UPDATE ON public.rental
    FOR EACH ROW
      EXECUTE FUNCTION public.fn_rental_trigger();

如果需要每行 运行ning,但是,这也不会执行该过程,因此我尝试更新的 table 永远不会收到任何数据。

要触发所有数据更改事件的触发器,请将 事件 编码为 INSERT OR UPDATE OR DELETE:

CREATE TRIGGER tr_new_rentals
AFTER INSERT OR UPDATE OR DELETE ON public.rental
FOR EACH ROW
    EXECUTE FUNCTION public.fn_rental_trigger()

由于前10条数据只依赖于表中的数据,而不是导致数据变化的事件(插入、更新或删除),所以触发器可以安全地定义为所有数据变化事件的一个触发器。