Я пытаюсь написать правило для представления для удаления кортежей из таблиц компонентов, но пока могу удалить данные только из одной из них.Некоторое время я использовал postgres с базовыми представлениями, но у меня нет опыта работы с правилами для представлений.
Я написал небольшой глупый тестовый пример, чтобы выяснить / показать мою проблему.В этом примере только один родительский кортеж на дочерний кортеж (моя настоящая схема на самом деле не такая).
Таблицы компонентов:
CREATE TABLE parent(
id serial PRIMARY KEY,
p_data integer NOT NULL UNIQUE
);
CREATE TABLE child(
id serial PRIMARY KEY,
parent_id integer NOT NULL UNIQUE REFERENCES parent(id),
c_data integer NOT NULL
);
Представление:
CREATE TABLE child_view(
id integer,
p_data integer,
c_data integer
);
CREATE RULE "_RETURN" AS ON SELECT TO child_view DO INSTEAD
SELECT child.id, p_data, c_data
FROM parent JOIN child ON (parent_id=parent.id);
Правило удаления проблемы
CREATE RULE child_delete AS ON DELETE TO child_view DO INSTEAD(
DELETE FROM child WHERE id=OLD.id;
DELETE FROM parent WHERE p_data=OLD.p_data;
);
Цель этого правила состоит в том, чтобы удалить кортежи, на которые имеются ссылки в представлении, изТаблицы компонентов.WHERE p_data=OLD.p_data
мне кажется странным, но я не вижу, как еще ссылаться на нужный кортеж в родительской таблице.
Вот что происходит, когда я пытаюсь использовать указанное выше правило:
>SELECT * FROM child_view;
id | p_data | c_data
----+--------+--------
1 | 1 | 10
2 | 2 | 11
3 | 3 | 12
(3 rows)
>DELETE FROM child_view WHERE id=3;
DELETE 0
>SELECT * FROM child_view;
id | p_data | c_data
----+--------+--------
1 | 1 | 10
2 | 2 | 11
(2 rows)
Но, глядя на родительскую таблицу, вторая часть удаления не работает (id = 3 "должен" был удален):
>SELECT * FROM parent;
id | p_data
----+--------
1 | 1
2 | 2
3 | 3
(3 rows)
Как мне написать правило удаления вудалить дочерний и родительский кортежи?
Это использует postgres v9.
Любая помощь приветствуется.Также приветствуются ссылки на любые материалы, касающиеся правил представлений за пределами документации postgres (если я явно не пропустил что-то).Спасибо.
РЕДАКТИРОВАТЬ: как указывает jmz, было бы проще использовать каскадное удаление, чем правило здесь, но этот подход не работает для моей реальной схемы.