【发布时间】:2020-01-20 12:59:07
【问题描述】:
我允许我的用户按回复计数排序并将其编入索引,以便操作快速。我使用以下 SQL 维护帖子的回复计数(对于递增的一半,还有一组等效的两个函数):
CREATE TRIGGER post_reply_count_decrement_update
BEFORE DELETE ON
public.convo_reply for each row execute function trigger_function_decrement_reply_count();
-
CREATE OR REPLACE FUNCTION public.trigger_function_decrement_reply_count()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
UPDATE post SET reply_count = reply_count - 1 WHERE post.convo_id = OLD.convo_id;
RETURN OLD;
END;
$function$;
我现在正在尝试运行这个命令:DELETE FROM convo WHERE convo_id = 1000031;
不幸的是,它不起作用,并且给了我这个错误:
SQL Error [23503]: ERROR: insert or update on table "post" violates foreign key constraint
"post_convo_id_fk"
Detail: Key (convo_id)=(1000031) is not present in table "convo".
Where: SQL statement "UPDATE post SET reply_count = reply_count - 1 WHERE post.convo_id = OLD.convo_id"
PL/pgSQL function trigger_function_decrement_reply_count() line 3 at SQL statement
SQL statement "DELETE FROM ONLY "public"."convo_reply" WHERE $1 OPERATOR(pg_catalog.=) "convo_id""
我认为这是因为 convo 条目被删除,然后触发器中的值返回 NULL,所以触发器出错了。
不过,这不是问题,因为无论如何,在帖子被删除后,回复计数都会立即设置为 0。也许有一种方法可以在运行时以某种方式禁用触发器? (虽然我当然仍然希望它能够为其他职位运行)
我还想保持触发器相当快,因为它会在每次创建或销毁回复时运行。
【问题讨论】:
标签: sql postgresql database-trigger cascading-deletes