如何编写PostgreSQL触发器函数阻止删除关联供应商记录
问题背景
我有两张表:
CREATE TABLE public.t_products ( product_id integer NOT NULL, product_name character varying(100) COLLATE pg_catalog."default" NOT NULL, supplier_id integer NOT NULL, CONSTRAINT t_products_pkey PRIMARY KEY (product_id) ); CREATE TABLE public.t_suppliers ( supplier_id integer NOT NULL, supplier_name character varying(100) NOT NULL, CONSTRAINT t_suppliers_pkey PRIMARY KEY (supplier_id) );
我希望编写一个函数,当t_suppliers中的供应商ID在t_products表中被引用时,禁止删除该供应商记录。我知道可以通过外键实现此功能,但想学习如何编写自定义函数,请问该函数的函数体应如何编写?
已定义触发器如下:
CREATE TRIGGER deleting_supplier BEFORE DELETE ON t_suppliers FOR EACH ROW EXECUTE PROCEDURE is_del_possible();
函数框架如下:
CREATE OR REPLACE FUNCTION is_del_possible() RETURNS trigger AS $$BEGIN ??? END;$$ LANGUAGE plpgsql;
自定义触发器函数实现
你可以通过查询t_products表检查当前待删除的供应商是否存在关联记录,若存在则抛出异常阻止删除。完整函数体如下:
CREATE OR REPLACE FUNCTION is_del_possible() RETURNS trigger AS $$BEGIN -- 检查待删除供应商是否被产品表引用 IF EXISTS ( SELECT 1 FROM public.t_products WHERE supplier_id = OLD.supplier_id ) THEN -- 抛出异常中断删除,给出明确提示 RAISE EXCEPTION '供应商ID % 仍有产品关联,无法删除', OLD.supplier_id; END IF; -- 无关联则返回OLD,允许执行删除 RETURN OLD; END;$$ LANGUAGE plpgsql;
逻辑说明
OLD.supplier_id:在BEFORE DELETE触发器中,OLD代表即将被删除的记录行,通过它可获取目标供应商ID。EXISTS子查询:高效判断t_products中是否存在使用该供应商ID的记录,只要有匹配行就返回true。RAISE EXCEPTION:检测到关联记录时,抛出异常终止删除操作,同时返回自定义错误提示。RETURN OLD:未检测到关联时,返回OLD表示允许执行后续删除流程(BEFORE DELETE触发器要求必须返回OLD或NULL,返回NULL会取消删除)。
测试验证
尝试删除有产品关联的供应商时,会收到如下错误提示:
ERROR: 供应商ID 1 仍有产品关联,无法删除 CONTEXT: PL/pgSQL function is_del_possible() line 6 at RAISE
内容的提问来源于stack exchange,提问作者pawel_wpf
相关产品推荐
相关产品推荐

