简体   繁体   中英

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. 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. 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.

PROBLEM

Evertything works fine except that no data is deleted in the table 'USERS_DIRECTORIES'. The references are deleted correctly in the 'SUB_DIRECTORIES' table tho. 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.

After much time asking Google for solutions I don't find anything about my issue. 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.

RETURN OLD; for BEFORE DELETE trigger (this you have wrong), RETURN NEW; for AFTER DELETE.

You can also use OLD in AFTER DELETE triggers, so safest is to always return OLD in DELETE trigger.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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