2013-08-20 16 views
2

我有parentchild表,其中child有一个FK指向父表的PK。当我在父表中删除某些东西时,我可以通过ON DELETE CASCADE删除子记录。针对外键约束的条件CASCADE操作?

但是,在我的parent表中,我根本不删除记录。相反,我设置了列state = "passive"。我想删除child表中的相关条目。

我们在Postgres中是否有类似“条件CASCADE”的东西?或者是手动删除child表中的条目的解决方案?

回答

1

你将不得不在一个触发器中执行此操作ON UPDATE。 NEW.state =“passive”的地方,删除子行。

+0

嗯,是的,它总是创建触发器的选项,但是我在想,如果我们有一些像Postgres里还是在为此事的任何RDBMS有条件的级联。无论如何,非常感谢您的回复。我很感激! – Kaunteya

+0

对不起,PostgreSQL土地上没有这样的动物。 –

0

没有什么像“条件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();