Удалить таблицу форм не работает PSQL - PullRequest
0 голосов
/ 03 июля 2018

Итак, я сейчас работаю над 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» с правильным запросом и идентификатором.

Спустя много времени, спрашивая у Google решения, я ничего не нашел в своей проблеме. Более того, я не являюсь носителем английского языка, поэтому трудно найти хорошие ключевые слова, определяющие мою проблему. Если кто-нибудь может помочь мне в этом, я буду очень благодарен.

PS: я тоже могу говорить по-французски, если это поможет.

1 Ответ

0 голосов
/ 03 июля 2018

RETURN OLD; для триггера BEFORE DELETE (это вы ошиблись), RETURN NEW; для AFTER DELETE.

Вы также можете использовать OLD в триггерах AFTER DELETE, поэтому безопаснее всего всегда возвращать OLD в триггере DELETE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...