【发布时间】:2026-01-20 18:40:01
【问题描述】:
我遇到了一个问题,这让我怀疑 Postgres 仅在 在它已经删除了原始行之后才从依赖表中删除行(ON DELETE CASCADE)。
我有这些表:
CREATE TABLE IF NOT EXISTS function (
id UUID PRIMARY KEY,
level VARCHAR(4) NOT NULL CHECK (level IN ('ORG', 'DEP', 'GRP', 'SESS')),
name VARCHAR(64) NOT NULL UNIQUE,
type VARCHAR(15) NOT NULL CHECK (type IN ('SYSTEM', 'SYS-AUTO-ASSIGN', 'CUSTOM'))
);
CREATE TABLE IF NOT EXISTS function_inclusion (
super_function UUID REFERENCES function (id) ON DELETE CASCADE,
sub_function UUID REFERENCES function (id) ON DELETE CASCADE,
UNIQUE (super_function, sub_function)
);
我在 function_inclusion 表上创建了一个触发器(在删除之前):
CREATE OR REPLACE FUNCTION trg_function_inclusion_del_bef()
RETURNS trigger AS
$func$
DECLARE
function_type VARCHAR(15);
BEGIN
SELECT type INTO function_type FROM function WHERE id = OLD.super_function;
RAISE NOTICE 'function_type: %', function_type;
-- do stuff based on the function_type of the super_function
CASE
WHEN function_type = 'SYSTEM' OR function_type = 'SYS-AUTO-ASSIGN' THEN
-- (do stuff)
WHEN function_type = 'CUSTOM' THEN
-- (do stuff)
ELSE RAISE EXCEPTION 'The function % doesn''t have a correct type', OLD.super_function;
END CASE;
RETURN OLD;
END
$func$
LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS function_inclusion_delete_before ON function_inclusion CASCADE;
CREATE TRIGGER function_inclusion_delete_before
BEFORE DELETE ON function_inclusion
FOR EACH ROW
EXECUTE PROCEDURE trg_function_inclusion_del_bef();
假设我有 2 个函数和一个 function_inclusion:
INSERT INTO function (id, level, name, type)
VALUES ('abcf3dbc-9433-4b73-b9c1-f00745dc1175', 'DEP', 'custom-function-1', 'CUSTOM');
INSERT INTO function (id, level, name, type)
VALUES ('360bde13-7953-49ed-a923-793b2d828d7e', 'DEP', 'custom-function-2', 'CUSTOM');
INSERT INTO function_inclusion (super_function, sub_function)
VALUES ('abcf3dbc-9433-4b73-b9c1-f00745dc1175', '360bde13-7953-49ed-a923-793b2d828d7e');
当我删除 super_function 时:
DELETE FROM function WHERE id = 'abcf3dbc-9433-4b73-b9c1-f00745dc1175';
我收到此错误:
NOTICE: function_type: <NULL>
Query 1 ERROR: ERROR: The function abcf3dbc-9433-4b73-b9c1-f00745dc1175 doesn't have a correct type
CONTEXT: PL/pgSQL function trg_function_inclusion_del_bef() line 13 at RAISE
SQL statement "DELETE FROM ONLY "public"."function_inclusion" WHERE $1 OPERATOR(pg_catalog.=) "super_function""
因此,该函数似乎已被删除,我无法再通过 function_inclusion 上的触发器访问它。
我试图找到有关“ON DELETE CASCADE”的更多信息,但我读到的所有地方都只说“引用行被自动删除”,没有提及首先删除的是引用行还是被引用行。
postgres 在删除相关(引用)表中的行之前是否首先删除原始(引用)行? 如果是这样,我怎样才能实现相同的东西,而不必在我的 function_inclusion 表中存储冗余数据?
【问题讨论】:
标签: sql postgresql triggers plpgsql cascade