我有parent
和child
表,其中child
有一个FK指向父表的PK。当我在父表中删除某些东西时,我可以通过ON DELETE CASCADE
删除子记录。针对外键约束的条件CASCADE操作?
但是,在我的parent
表中,我根本不删除记录。相反,我设置了列state = "passive"
。我想删除child
表中的相关条目。
我们在Postgres中是否有类似“条件CASCADE”的东西?或者是手动删除child
表中的条目的解决方案?
我有parent
和child
表,其中child
有一个FK指向父表的PK。当我在父表中删除某些东西时,我可以通过ON DELETE CASCADE
删除子记录。针对外键约束的条件CASCADE操作?
但是,在我的parent
表中,我根本不删除记录。相反,我设置了列state = "passive"
。我想删除child
表中的相关条目。
我们在Postgres中是否有类似“条件CASCADE”的东西?或者是手动删除child
表中的条目的解决方案?
你将不得不在一个触发器中执行此操作ON UPDATE。 NEW.state =“passive”的地方,删除子行。
没有什么像“条件CASCADE”。想到的最接近的东西是disable triggers。但是这对你的情况没有帮助。
假设:
- state
定义NOT NULL
。
- parent_id
从来没有的变化。如果是这样,您还需要级联该UPDATE。当家长设置为“被动”
NEW.state = "passive"
AND OLD.state <> "passive"
..因为你不想一遍又一遍触发它,只有一次:
条件来触发触发器ON UPDATE
应该的。
CREATE OR REPLACE FUNCTION trg_upbef()
RETURNS TRIGGER AS
$func$
BEGIN
DELETE FROM child
WHERE parent_id = OLD.parent_id; -- OLD works for UPDATE & DELETE
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
相反的checking the condition in the trigger function, you can do that in the trigger directly since Postgres 9.0,从而节省一点开销:
CREATE TRIGGER upd_cascade_del
BEFORE UPDATE ON parent
FOR EACH ROW
WHEN (NEW.state = "passive" AND
OLD.state <> "passive") -- parenthesis required
EXECUTE PROCEDURE trg_upbef();
不要忘记添加一个触发ON DELETE
为好。您通常不会删除,但如果您这样做,则希望引发异常或级联操作。
触发功能必须RETURN OLD
,因为NEW在这种情况下没有定义。否则相同:
CREATE OR REPLACE FUNCTION trg_delbef()
...
RETURN OLD;
...
$func$ LANGUAGE plpgsql;
CREATE TRIGGER del_cascade_del
BEFORE DELETE ON parent
FOR EACH ROW
WHEN (OLD.state <> "passive") -- only if not already passive
EXECUTE PROCEDURE trg_delbef();
嗯,是的,它总是创建触发器的选项,但是我在想,如果我们有一些像Postgres里还是在为此事的任何RDBMS有条件的级联。无论如何,非常感谢您的回复。我很感激! – Kaunteya
对不起,PostgreSQL土地上没有这样的动物。 –