简体   繁体   English

删除表单表不起作用psql

[英]Delete form table doesn't work psql

So I'm currently working on PostgreSQL (10.4) and need to simulate a "file system" within my database. 因此,我当前正在使用PostgreSQL(10.4),需要在数据库中模拟“文件系统”。 In order to achieve this goal I have two tables : 为了实现此目标,我有两个表:

-- 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
);

The issue occur when I need to delete a directory. 当我需要删除目录时,会发生此问题。 In order to do it correctly I need to delete all sub directories. 为了正确执行此操作,我需要删除所有子目录。

CURRENT SOLUTION 当前解决方案

To delete a sub directory I need to delete its reference in the 'SUB_DIRECTORIES' tables to not trigger the foreign key exception. 要删除子目录,我需要在“ SUB_DIRECTORIES”表中删除其引用,以免触发外键异常。 to solve this problem I use two triggered procedures. 为了解决这个问题,我使用了两个触发过程。

-- 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();

Whenever I delete a directory it triggers 'delete_reference()' function which remove all references of the directory from the tables 'SUB_DIRECTORIES' and when I delete a references from the very same table it triggers the 'delete_refered()' functions which delete the sub_directories and it goes on and on recursively. 每当我删除目录时,它都会触发“ delete_reference()”函数,该函数将从表“ SUB_DIRECTORIES”中删除该目录的所有引用;当我从同一张表中删除引用时,它会触发“ delete_refered()”函数,该函数将删除sub_directories并不断进行下去。

PROBLEM 问题

Evertything works fine except that no data is deleted in the table 'USERS_DIRECTORIES'. 一切正常,除了在表“ USERS_DIRECTORIES”中未删除任何数据外。 The references are deleted correctly in the 'SUB_DIRECTORIES' table tho. 在“ SUB_DIRECTORIES”表中已正确删除了引用。 Eventhough I try to delete 'by hand' a specific row in the table 'USERS_DIRECTORIES' ('delete from ... where id = ..') it ends up with 'DELETE 0' with a correct query and id. 尽管我尝试“手动”删除表“ USERS_DIRECTORIES”中的特定行(“从...中删除,其中id = ..”),但最终以“ DELETE 0”结尾,并带有正确的查询和ID。

After much time asking Google for solutions I don't find anything about my issue. 经过很多时间向Google寻求解决方案后,我没有发现有关我的问题的任何信息。 Moreover I'm not a native english speaker so it is hard to find good key words defining my problem. 此外,我不是英语为母语的人,因此很难找到定义我的问题的关键词。 If anyone can help me on this one I'll be very grateful. 如果有人可以帮助我,我将非常感激。

PS : I can speak french too if it helps. PS:如果有帮助,我也可以说法语。

RETURN OLD; for BEFORE DELETE trigger (this you have wrong), RETURN NEW; 对于DELETE触发器之前(此操作有误),请RETURN NEW; for AFTER DELETE. 用于“删除后”。

You can also use OLD in AFTER DELETE triggers, so safest is to always return OLD in DELETE trigger. 您还可以在AFTER DELETE触发器中使用OLD ,因此最安全的方法是始终在DELETE触发器中返回OLD

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM