【问题标题】:Conditional CASCADE operation for foreign key constraint?外键约束的条件级联操作?
【发布时间】:2013-08-22 14:40:50
【问题描述】:

我有parentchild 表,其中child 有一个指向父表PK 的FK。当我删除父表中的某些内容时,我也可以通过 ON DELETE CASCADE 删除子记录。

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

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

【问题讨论】:

    标签: sql postgresql triggers foreign-keys sql-delete


    【解决方案1】:

    您必须在执行更新操作的触发器中执行此操作。其中NEW.state="passive",删除子行。

    【讨论】:

    • 嗯,是的,创建触发器始终是一个选项,但是我想知道我们是否在 Postgres 或任何 RDBMS 中有类似条件级联的东西。无论如何,非常感谢您的回复。我很感激!
    • 抱歉,PostgreSQL 大陆上没有这种动物。
    【解决方案2】:

    没有什么比得上“条件级联”了。想到的最接近的事情是disable triggers。但这对您的情况没有帮助。

    假设:
    - state 定义为 NOT NULL
    - parent_id 从不改变。如果是这样,您还需要级联该 UPDATE。

    触发触发器ON UPDATE的条件应该是:

         NEW.state =  "passive"
    AND  OLD.state <> "passive"
    

    .. 因为你不想一遍又一遍地触发它,只有在 parent 设置为“被动”时才触发一次。

    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 添加触发器。您通常不会 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();
    

    【讨论】:

      猜你喜欢
      • 2011-02-24
      • 2014-01-17
      • 1970-01-01
      • 1970-01-01
      • 2011-01-01
      • 2019-12-24
      • 2019-04-26
      • 1970-01-01
      相关资源
      最近更新 更多