首页 > 解决方案 > 删除帖子时如何级联删除帖子中的回复?

问题描述

我允许我的用户按回复计数排序并将其编入索引,以便操作快速。我使用以下 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。也许有一种方法可以在运行时以某种方式禁用触发器?(虽然我当然仍然希望它为其他职位运行)

我还想保持触发器相当快,因为​​每次创建或销毁回复时它都会运行。

标签: sqlpostgresqldatabase-triggercascading-deletes

解决方案


您可以在运行查询之前尝试禁用特定触发器

ALTER TABLE public.convo_reply DISABLE TRIGGER post_reply_count_decrement_update;

或抓到违规

EXCEPTION WHEN others THEN
....

或者检查帖子是否存在,改变整体逻辑。例如,在发布表上运行触发器,更改创建索引的表...


推荐阅读