2009-06-13 8 views
9

He la siguiente estructura de base de datos en SQLite:desencadenantes en cascada en SQLite

db structure http://i39.tinypic.com/kb3qef.jpg

Quiero crear un disparador que cada vez que elimino un país también se eliminan todos los distritos relacionados, municipios y parroquias (como MySQL InnoDB), he intentado usar disparadores SQLite y se acercó con esto:

distritos:

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

municipios:

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

Parroquias:

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

todavía no he probado el delete_district y delete_municipality desencadena porque consigo un comportamiento extraño en el delete_country de disparo: cuando se borra una país solo el primer distrito relacionado se borra, todos los otros distritos relacionados permanecen en la tabla. ¿Qué estoy haciendo mal?

+4

¿Qué se utiliza para crear los gráficos ? – Nifle

+0

http://ondras.zarovi.cz/sql/ –

Respuesta

13

El disparador parece que se está eliminando los distritos cuya identificación es igual a id_countries, es decir, la cláusula where es en realidad

WHERE districts.id_countries = districts.id 

Es necesario hacer referencia a la ID de la tabla de países. En un desencadenador de eliminación, use "viejo" para hacer esto.

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

Además, le sugiero que cambie su convención de nomenclatura de esquemas. Por lo general, el nombre de la tabla es singular y corresponde a la entidad en una fila. Me gustaría tener una tabla de país con las columnas ID y el nombre, una mesa distrito con id, country_id y el nombre, etc.

country 
------- 
id 
name 

district 
------- 
id 
country_id 
name 

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

parish 
----- 
id 
municipality_id 
name 

Entonces el gatillo habría

CREATE TRIGGER [delete_country] 
BEFORE DELETE 
ON [country] 
FOR EACH ROW 
BEGIN 
DELETE FROM district WHERE district.country_id = old.id; 
END 
+1

Muchas gracias por su ayuda, lo antiguo funcionó muy bien. =) –

Cuestiones relacionadas