2009-06-13 9 views
9

Ich habe die folgende DB-Struktur in SQLite:Cascade Trigger in SQLite

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

Ich möchte einen Auslöser schaffen, dass, wenn ich ein Land alle zugehörigen Bezirke löschen, Kommunen und Gemeinden werden ebenfalls gelöscht (wie MySQL InnoDB), habe ich mit diesem SQLite Trigger und kam mit versucht:

Bezirke:

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

Gemeinden:

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

Parishes:

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

Ich habe getestet noch nicht die delete_district und delete_municipality auslöst, weil ich ein seltsames Verhalten auf dem delete_country Trigger erhalten: wenn ich ein löschen Land nur der erste verwandte Bezirk wird gelöscht, alle anderen verwandten Bezirke bleiben in der Tabelle. Was mache ich falsch?

+4

sein, was Sie die Grafiken erstellt haben verwenden ? – Nifle

+0

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

Antwort

13

Der Auslöser sieht aus wie es ist Bezirke, deren ID gleich id_countries löschen, das heißt, die where-Klausel tatsächlich

WHERE districts.id_countries = districts.id 

Sie brauchen, ist die ID aus der Länder-Tabelle zu verweisen. Verwenden Sie in einem Löschtrigger "alt", um dies zu tun.

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

Auch würde ich vorschlagen, Ihre Schemanamenskonvention zu ändern. Normalerweise ist der Tabellenname singulär und entspricht der Entität in einer Zeile. Ich würde ein Land Tabelle mit Spalten-ID und Namen hat, ein Viertel Tisch mit id, country_id und Namen usw.

country 
------- 
id 
name 

district 
------- 
id 
country_id 
name 

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

parish 
----- 
id 
municipality_id 
name 

Dann würde der Auslöser

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

Vielen Dank für Ihre Hilfe, das alte Ding hat einfach super funktioniert. =) –