Immi: SQL DELETE über mehrere Tabellen?

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

  1. Hello,

    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

    zunächst mal, WAS für ein Datenbankserver ist denn das? Aus der Fehlermeldung werde ich da mal nicht schlauer.
    Danach wäre meine nächste Frage, warum du denn DELETE xyz FROM schreibst, anstelle von DELETE FROM ...?
    Meiner Erfahrung nach sind da gewisse DBMS nämlich nicht so richtig glücklich. Daran schließt sich dann die Frage an, was denn das Ergebnis von
    DELETE FROM statistik, kasse, journal WHERE ...
    ist?

    Schlussendlich eine Anmerkung: Es wäre möglich, dass deine DELETE-Anweisung tatsächlich nicht in einem Schritt möglich ist. Das DBMS muss schließlich beim Löschen für jede einzelne Tabelle nachvollziehen können, welche Tupel von der Anweisung betroffen sind und welche nicht. Wenn deine Kriterienliste und/oder Beziehungen dazu nicht ausreichen, dann wird das nicht klappen.
    Ich bin sowieso etwas zögerlich, was Löschen aus mehreren Tabellen angeht, Einfügen/Löschen aus Views (das wird dein Kollege gemeint haben) ist mir bekannt, Mehrfachlöschen in einem Statement habe ich selbst noch nicht verwendet.

    MfG
    Rouven

    --
    -------------------
    He is entertaining both out of the car and in the car because if you tell him that a corner is almost flat then he is the guy who is going to try to take it flat even if it means shunting it the other side of it, he will come with the data and say 'hey, I may have crashed and destroyed the car, but I was flat-out'. That is an interesting quality that he has!  --  Team Member on Jacques Villeneuve
    1. Hi

      tut mir leid, es ist ein MSSQL Server 2000 auf dem das Query laufen soll!

      @Frank: Ich denke, alle drei Varianten sind mit MSSQL durchführbar, oder?

      @Rouven:

      Danach wäre meine nächste Frage, warum du denn DELETE xyz FROM schreibst, anstelle von DELETE FROM ...?

      Ich wollte ja die Daten aus allen drei Tabellen löschen und wenn ich nur folgendes geschrieben habe:

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

      Funktionierte es auch nicht. Deshalb hab ich bei DELETE noch die Tabelle reingeschrieben. Aber so löscht er ja nur die Zeilen aus der Tabelle, die ich angegeben habe und wenn ich das Query nochmals auf die anderen Tabellen anwenden möchte, ist logischerweise der Inhalt für den Vergleich bei der WHERE Bedingung nicht mehr vorhanden.

      Was referentielle Integrität anbelangt müsste ich mich erst einarbeiten, ich war jetzt 10 Monate im Militär und bin nicht mehr auf dem neusten Stand. :(

      Gibt es eine Möglichkeit, indem man die DELETE Anweisungen innerhalb eines SELECT's macht?

      lg

      1. Hallo,

        ja, alles dreis geht auf MS SQL 2000. Es hängt auch ein wenig davon ab, wie du auf MS SQL Zugreifst, z.b. ob du die Möglichkeit hast, Transaktionen über die API (ADO, ADO.Net, Perl, PHP) zu erzeugen oder nicht.

        Du kannst ein DELETE auch mit einem JOIN von anderen Tabellen abhängig machen (genauso wie man das bei UPDATE kann), das ist ein nicht so häufig benutztes Feature, aber funktioniert wunderbar. Konsultiere dazu bitte deine MS SQL Dokumentation (SQL Books Online genannt). Unter dem Stichwort DELETE solltest du da fündig werden.

        Referentielle Integrität ... nur wenn du Fremdschlüssel (Foreign Keys) benutzt, dann hängst du an diese CONSTRAINT Definitionen jeweils noch: ON DELETE CASCADE. Schlage dazu am besten ebenfalls unter SQL Books Online nach (bei CREATE TABLE oder ALTER TABLE)

        Gibt es eine Möglichkeit, indem man die DELETE Anweisungen innerhalb eines SELECT's macht?

        Wie meinen bitte? Wie soll das gehen? DELETE ist DELETE und SELECT ist SELECT. Das sind zwei verschiedene DML Anweisungen.

        Gruss,
        Frank

  2. Hi,

    MS-SQL? mySQL? irgendein anderes SQL?

    Variante 1: Benutze "Referentielle Integrität" soweit von der DB her möglich

    Variante 2: Benutze explizite Transaktionen (BEGIN TRAN ... COMMIT TRAN) und packe alle deine Delete Statements dazwischen. Deine DB API sollte natürlich explizite Transaktionen unterstützen.

    Variante 3: Schreibe eine Prozedur (quasi eine funktionale Abstraktion deiner Löschfunktion) und führe darin die 3 DELETE Anweisungen aus. Deine DB sollte natürlich "Gespeicherte Prozeduren" unterstützen.

    Ein Kolleg hat was von ner Zwischentabelle oder so ...

    Aha. Fast-zinierend.

    Gruss,
    Frank

    1. Variante 3: Schreibe eine Prozedur (quasi eine funktionale Abstraktion deiner Löschfunktion) und führe darin die 3 DELETE Anweisungen aus. Deine DB sollte natürlich "Gespeicherte Prozeduren" unterstützen.

      Wobei zumindest mir nicht ganz klar ist, was im Fehlerfall passiert, kommt es vielleicht zu Teilausführungen?

      Nicht schlecht auf jeden Fall der Nachbau von Transaktionen auf PHP- oder Perl-Ebene. Wenn auch zweite Wahl natürlich.   ;)

      1. Hi Ludger,

        Wobei zumindest mir nicht ganz klar ist, was im Fehlerfall passiert, kommt es vielleicht zu Teilausführungen?

        Wenn von ausserhalb über die API (PHP, ASP, Perl) ein Transaktionskontext existiert, sollte es nicht zu Teilausführungen kommen. Der OP hat leider nicht viel Angaben gemacht, wie er gedenkt, die Löschung auszuführen, deswegen kamen die 3 Pauschallösungen

        Nicht schlecht auf jeden Fall der Nachbau von Transaktionen auf PHP- oder Perl-Ebene. Wenn auch zweite Wahl natürlich.   ;)

        Dass ich das als Variante 2 hatte, hat nichts mit der "Wertung als 2. Option" zu tun. Ich würde es sogar gegenüber Referentieller Integrität bevorzugen (aus praktischer Erfahrung), da RI ein technisches Feature ist und nicht unbedingt Hand-in-Hand mit der gewünschten Geschäftslogik gehen muss.

        Cheers,
        Frank