因此,我目前正在使用PostgreSQL(10.4),并且需要在数据库中模拟“文件系统”。为了实现此目标,我有两个表:
-- represent a directory
CREATE TABLE USERS_DIRECTORIES
(
id SERIAL NOT NULL,
users_id INTEGER NOT NULL,
name VARCHAR(64) NOT NULL,
description VARCHAR(64) NOT NULL DEFAULT '',
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
UNIQUE(users_id, name),
PRIMARY KEY (id),
FOREIGN KEY (users_id) REFERENCES USERS(id)
);
-- represent links between a directory and its sub-directories
CREATE TABLE SUB_DIRECTORIES
(
id SERIAL NOT NULL,
-- parent directory
parent_id INTEGER,
-- sub directory
child_id INTEGER NOT NULL,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
PRIMARY KEY (id),
FOREIGN KEY (parent_id) REFERENCES USERS_DIRECTORIES(id),
FOREIGN KEY (child_id) REFERENCES USERS_DIRECTORIES(id) ON DELETE CASCADE
);
当我需要删除目录时,会发生此问题。为了正确执行此操作,我需要删除所有子目录。
当前解决方案
要删除子目录,我需要在“ SUB_DIRECTORIES”表中删除其引用,以免触发外键异常。为了解决这个问题,我使用了两个触发过程。
-- triggered when I delete a directory to delete a reference
CREATE OR REPLACE FUNCTION delete_reference()
RETURNS TRIGGER AS
$$
BEGIN
raise notice 'OLD: %', OLD.id;
DELETE FROM sub_directories WHERE parent_id = OLD.id;
IF FOUND THEN
raise notice 'SUCESS id : %', OLD.id;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER on_delete_sub_references BEFORE DELETE ON users_directories
FOR EACH ROW
EXECUTE PROCEDURE delete_reference();
-- triggered when I delete a reference to delete all sub directories
CREATE OR REPLACE FUNCTION delete_refered()
RETURNS TRIGGER AS
$$
BEGIN
raise notice 'OLD child: %', OLD.child_id;
DELETE FROM users_directories WHERE id = OLD.child_id;
IF FOUND THEN
raise notice 'SUCESS child_id : %', OLD.child_id;
END IF;
RETURN NEW;
EXCEPTION
WHEN OTHERS THEN
raise notice 'EXCEPTION';
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER on_delete_sub_refered AFTER DELETE ON sub_directories
FOR EACH ROW
EXECUTE PROCEDURE delete_refered();
每当我删除目录时,它都会触发“ delete_reference()”功能,该功能会从表“ SUB_DIRECTORIES”中删除该目录的所有引用;当我从同一张表中删除引用时,它会触发“ delete_refered()”功能,删除子目录,然后递归地进行下去。
问题
除了在表“ USERS_DIRECTORIES”中没有删除任何数据外,一切都可以正常工作。在“ SUB_DIRECTORIES”表中已正确删除了引用。 即使我尝试“手工”删除表“ USERS_DIRECTORIES”中的特定行(“从...删除,其中id = ..”),但最终以“ DELETE 0”结尾,并带有正确的查询和ID。
花了很多时间问Google解决方案之后,我没有发现任何关于我的问题的信息。此外,我不是英语为母语的人,因此很难找到定义我的问题的关键词。如果有人可以帮助我,我将非常感激。
PS:如果有帮助,我也可以说法语。
答案 0 :(得分:0)
RETURN OLD;
用于“删除前”触发器(此操作有误),RETURN NEW;
用于“删除后”。
您还可以在AFTER DELETE触发器中使用OLD
,因此最安全的方法是始终在DELETE触发器中返回OLD
。