# DELETE über drei Tabellen?



## Immi (21. Mai 2007)

Hallo zusammen!

Ich habe ein kleines SQL Problem. Ich will mehrere Zeilen aus 3 verschiedenen Tabellen löschen.

Wenn ich das Querry nun so schreibe:


```
DELETE Statistik 
FROM Statistik,Kasse,Journal
WHERE (Statistik.TischNr = 1124)
AND (Statistik.BuchPeriode BETWEEN '01.08.2004' AND '31.08.2004')
AND (Kasse.BonNr = Journal.BonNr)
```

Dann löscht er mir logischerweise nur den Inhalt aus der Statistik Tabelle und lässt mir die Zeilen in der Kasse und der Journal Tabelle.

Wenn ich folgendes versuche, kommt der Fehler "Server: Nachr.-Nr. 170, Schweregrad 15, Status 1, Zeile 1
Zeile 1: Falsche Syntax in der Nähe von ','."


```
DELETE Statistik, Kasse, Journal
FROM Statistik,Kasse,Journal
WHERE (Statistik.TischNr = 1124)
AND (Statistik.BuchPeriode BETWEEN '01.08.2004' AND '31.08.2004')
AND (Kasse.BonNr = Journal.BonNr)
```

Hat jemand ne Lösung wie ich das Ergebnis in allen drei Tabellen löschen kann? Ein Kolleg hat was von ner Zwischentabelle oder so gesagt, doch sagt mir das jetzt gar nichts? :S

Vielen Dank bereits für Eure Bemühungen!

lg Immi


----------



## lmarkus31 (21. Mai 2007)

Hallo,

ein DELETE über 3 Tabellen einfach so wäre mir neu.
Welche Datenbank verwendest Du?

Was die Datenbank für dich erledigen kann, ist die sogenannte Löschweitergabe, d.h. bei   deinen Detailtabellen definierst du den Fremdschlüssel mit "ON DELETE CASCADE", sofern das deine Datenbank unterstützt. Das sähe dann z.B.so aus:
Dann würden die Detaildatensätze automatisch aus den Detailtabellen gelöscht werden, sobald der Eintrag aus der Mastertabelle gelöscht wurde. Damit bleibt die referentielle Integrität gewahrt.


```
ALTER TABLE <detailtabelle> 
  ADD CONSTRAINT fk_master 
  FOREIGN KEY(<fk_column>) 
  REFERENCES <mastertabelle>(pk_column) 
  ON DELETE CASCADE;
```

Zum zweiten wäre je nach Datenbank ein Datenbank-Trigger eine Möglichkeit, der automatisch nach dem Löschen eines Datensatzes aus der Mastertabelle aufgerufen wird z.B. so: (nicht getestet, nur zum Demonstrieren)


```
CREATE OR REPLACE TRIGGER delStat AFTER DELETE ON <mastertabelle>
FOR EACH ROW
BEGIN
   DELETE FROM detailtabelle1 WHERE <fk_column> = :old.pk_column;
   DELETE FROM detailtabelle2 WHERE <fk_column> = :old.pk_column;  
END;
```

Für <Mastertabelle> und <Detailtabelle> setzt du jetzt die jeweiligen Tabellennamen ein, die du benutzt, für <pk_column> die Spalte in der Mastertabelle, die den Primärschlüssel bildet, für <fk_column> setzt du die Spalte in der Detailtabelle, die für den Fremdschlüssel steht. 

Das ganze geht natürlich noch viel komplexer, aber ich hoffe es reicht als Demonstration.

Markus


----------



## Immi (21. Mai 2007)

Hi!

Danke dir erst mal für deine ausführliche Antwort!

Es ist ein MS SQL Server 2000, auf dem ich das Query laufen lassen will. Ich werde deinen Vorschlag morgen mal ausprobieren, hört sich hoffentlich komplizierter an als es ist! 

lg Immi


----------



## Immi (22. Mai 2007)

Ich bekomms leider nicht hin, so wie du es beschrieben hast.

Gibt es eine Möglichkeit, die Daten zuerst in ein Recordset zu lesen und anschliessend zu löschen? Oder ganz anders: Die Daten zuerst per UPDATE zu ändern z.b. in "123456" und dann einfach:

DELETE FROM Statistik WHERE BonNr = '123456'

Oder ist das ne schlechte Idee?

lg Immi


----------



## lmarkus31 (22. Mai 2007)

Hallo,

was ich vergass zu erwähnen, meine Lösung war für Oracle gedacht, nicht für SQL Server. Ich denke aber dass es Triigger und Löschweitergabe auch beim SQL-Server gibt.
Falls ich heute später nochmal Zeit hab schau ich gern nochmal nach wie es dort funktionieren würde.

Markus


----------



## Immi (22. Mai 2007)

lmarkus31 hat gesagt.:


> Hallo,
> 
> was ich vergass zu erwähnen, meine Lösung war für Oracle gedacht, nicht für SQL Server. Ich denke aber dass es Triigger und Löschweitergabe auch beim SQL-Server gibt.
> Falls ich heute später nochmal Zeit hab schau ich gern nochmal nach wie es dort funktionieren würde.
> ...



Wäre natürlich sehr nett von Dir! Bin immer noch am ausprobieren, doch klappen tut's leider immer noch nicht 

lg


----------



## Sparks (22. Mai 2007)

Hallo,

wie schon Imarkus31 schreibt, ist die referentielle Integrität sicher die "beste" (einfachste) Methode.
Je nach Version von SQL-Server geht das vlt. nicht, in V. 7.0 offenbar nicht:
http://www.berndjungbluth.de/sqlfaq/faqa3.htm#A3.5.

Von M$ erklärt, wie das bei SQL-Server 2005 funktioniert:
http://msdn2.microsoft.com/de-de/library/ms177288.aspx

Gruß,
Sparks


----------

