【发布时间】:2022-01-05 18:24:50
【问题描述】:
我正在尝试在表被更新(插入/删除/更新)时运行一个过程/函数,但是,当触发器发生或触发器没有被触发时,该函数似乎没有运行插入。
函数和触发器:
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());
存储过程按预期工作,当我单独运行它时,我得到了我想要的。从触发器运行它在我尝试的每一种方式中都失败了,那么运行触发器以在表更新上执行工作过程的正确方法是什么?
就上下文而言,这是基于 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();
但是,如果需要按行运行,那也不会执行该过程,因此我尝试更新的表永远不会收到任何数据。
【问题讨论】:
-
1)
get_top_ten_rentals()在做什么? 2) 执行INSERT时遇到什么错误? 3)你知道你是在每条语句还是每行运行这个? 4) 为什么不把get_top_ten_rentals()做成一个函数,这样你就可以直接在触发器中使用它了?添加答案以更新您的问题。 -
@AdrianKlaver 请查看对问题的修改
-
@CodeLee,伙计!周末休息,下周一回来!我很确定你累了:触发器是 UPDATE,而你正在执行 INSERT!
-
参见此处plpgsql trigger 示例 43.4。用于审计的 PL/pgSQL 触发器函数。它列出了您需要遵循的模式。
-
@MarcusViniciusPompeu:SQL Server 中没有
updated伪表 - 只有inserted和deleted。对于UPDATE,inserted表包含UPDATE操作之后的新 值,而deleted包含UPDATE之前存在的值 ...
标签: sql postgresql stored-procedures triggers