我希望能够为外键ON DELETE约束执行一些逻辑。根据逻辑,我要么想要CASCADE或RESTRICT。
我的桌子:
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
);
在我的(非常基本的)表格中,document
和/或user
可以拥有team
。
关于documents
,如果有人删除文档的用户并且文档的team_id
为空,则CASCADE删除到文档(反之亦然,用user_id和team_id)。
否则,如果有人删除了文档的用户并且文档的team_id
不是NULL,则限制删除用户(反之亦然,使用user_id和team_id)。
我在文档中没有看到任何完成此操作的方法。我是否需要在服务器代码中而不是在数据库中执行此逻辑?我想要额外的数据完整层。
答案 0 :(得分:2)
这很可能,但不是直接的。你需要一个触发器。首先将外键设置为RESTRICT
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();
而且我相信这正是你正在寻找的。 p>