我希望能够对删除约束上的外键执行一些逻辑。根据逻辑,我要么要级联,要么要限制。
我的桌子:

CREATE TABLE users (
  user_id uuid DEFAULT uuid_generate_v4() PRIMARY KEY
);

CREATE TABLE teams (
  team_id uuid DEFAULT uuid_generate_v4() PRIMARY KEY
);

CREATE TABLE documents (
  document_id uuid DEFAULT uuid_generate_v4() PRIMARY KEY
  user_id uuid REFERENCES users ON DELETE /*do logic here*/,
  team_id uuid REFERENCES teams ON DELETE /*do logic here*/,
  content text
);

在我的(非常基本的)表中,adocument可以由auser和/或ateam拥有。
关于documents,如果有人删除了文档的用户,并且文档的team_id为空,则将删除操作层叠到文档中(反之亦然,使用用户id和团队id)。
否则,如果有人删除了文档的用户,并且文档的team_id不为空,则限制删除该用户(反之亦然,用户id和团队id)。
我在文档中看不到任何实现这一点的方法。我需要在服务器代码中而不是数据库中执行此逻辑吗?我需要额外的数据完整性层。

最佳答案

这是完全可能的,但不是直接的。你需要一个扳机。首先设置要限制的外键

CREATE TABLE documents (
  document_id uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
  user_id uuid REFERENCES users ON DELETE RESTRICT,
  team_id uuid REFERENCES teams ON DELETE RESTRICT,
  content text
);

然后为用户表创建触发器函数和触发器
CREATE OR REPLACE FUNCTION user_delete()
RETURNS TRIGGER AS $$
BEGIN
    DELETE FROM documents WHERE team_id IS NULL and user_id = OLD.user_id;
    RETURN OLD;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER user_delete_trigger BEFORE DELETE ON users FOR EACH ROW     EXECUTE PROCEDURE user_delete();

然后对团队表执行同样的操作。
CREATE OR REPLACE FUNCTION team_delete()
RETURNS TRIGGER AS $$
BEGIN
    DELETE FROM documents WHERE user_id IS NULL and team_id = OLD.team_id;
    RETURN OLD;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER team_delete_trigger BEFORE DELETE ON users FOR EACH ROW     EXECUTE PROCEDURE team_delete();

我相信这正是你想要的。

09-25 18:25
查看更多