Каскадные триггеры в SQLite - PullRequest
9 голосов
/ 13 июня 2009

У меня есть следующая структура БД в SQLite:

db structure

Я хочу создать триггер, который, когда бы я ни удалял страну, также удалялись все связанные районы, муниципалитеты и приходы (например, MySQL InnoDB), я пытался использовать триггеры SQLite и придумал следующее:

Районы:

CREATE TRIGGER [delete_country]
BEFORE DELETE
ON [countries]
FOR EACH ROW
BEGIN
DELETE FROM districts WHERE districts.id_countries = id;
END

Самоуправления:

CREATE TRIGGER [delete_district]
BEFORE DELETE
ON [districts]
FOR EACH ROW
BEGIN
DELETE FROM municipalities WHERE municipalities.id_districts = id;
END

Приходы:

CREATE TRIGGER [delete_municipality]
BEFORE DELETE
ON [municipalities]
FOR EACH ROW
BEGIN
DELETE FROM parishes WHERE parishes.id_municipalities = id;
END

Я еще не тестировал триггеры delete_district и delete_municipality, потому что при триггере delete_country я получаю странное поведение: при удалении страны удаляется только первый связанный район , все остальные связанные районы остаются в таблице. Что я делаю не так?

1 Ответ

13 голосов
/ 13 июня 2009

Триггер выглядит так, как будто он удаляет районы, чей идентификатор равен id_countries, то есть предложение where фактически

WHERE districts.id_countries = districts.id

Вам нужно указать идентификатор из таблицы стран. В триггере удаления используйте «old» для этого.

CREATE TRIGGER [delete_country]
BEFORE DELETE
ON [countries]
FOR EACH ROW
BEGIN
DELETE FROM districts WHERE districts.id_countries = old.id;
END

Кроме того, я бы предложил изменить соглашение об именах схем. Обычно имя таблицы является единственным и соответствует сущности в строке. У меня будет таблица стран с идентификаторами и именами столбцов, таблица районов с идентификаторами, идентификаторами и именами стран и т. Д.

country
-------
id
name

district
-------
id
country_id
name

municipality
------------
id
district_id
name

parish
-----
id
municipality_id
name

Тогда триггер будет

CREATE TRIGGER [delete_country]
BEFORE DELETE
ON [country]
FOR EACH ROW
BEGIN
DELETE FROM district WHERE district.country_id = old.id;
END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...