SQL Delete mit Inner Join will nicht

  • C#
  • .NET 4.0

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    SQL Delete mit Inner Join will nicht

    Moin,
    ich versuche gerade in einer C# Anwendung und SQLite eine Zeile zu Löschen in zwei Tabellen. Habe schon viel gegoogelt, aber überall steht fast das gleiche was gehen soll, bei mir aber nicht funktioniert.

    Beispie:

    SQL-Abfrage

    1. ​DELETE FROM Kunde INNER JOIN Bestellung ON Kunde.Kundennummer = Bestellung.Kundennummer WHERE Kundennummer = 1234
    nein, leider nicht.
    Das Anlegen von Datenbank-Tabellen via Sql finde ich so lausig, dass ich lieber eine Db verwende, die dafür einen Designer anbietet: Access oder SqlServer.
    Noch lieber verwende ich mein DbGenerator, der generiert mir die Db, wobei er als Vorlage ein typisiertes Dataset hernimmt.

    Übrigens könntest du den DbGenerator sogar glatt nehmen, wenn der solch generiert, dann zeigt er auch den verwendeten Sql-Code an.

    Noch lieber lasse ich die Db ganz weg - grad SqLite- dbs sind oft so klein dass sie auch ganz entbehrlich sind.
    ein typDataset benutze ich nicht. In den letzten Monaten habe ich aber alles mal probiert, nur um die unterschiede kennen zu lernen. Ist nie was produktives draus geworden, aber habe eine menge gelernt.
    Jetzt bin ich beim SQLite angekommen und wollte mir das mal ansehen. Der dbdesigner.net ist echt hübsch, gibt beim Export aber nicht die Verbindung zwischen den Tabellen mit aus. Ist ja auch noch Beta laut deren Seite, aber sonst ganz gut gemacht.

    Wenn der dbdesinger, egal welcher, richtig Arbeitet und man die Tabellen verbindet, würde auch z.b. das Löschen/Einfügen, Tabellen übergreifend funktionieren.

    Deine Video sind gut erklärt!

    Pardasus schrieb:

    Wenn der dbdesinger, egal welcher, richtig Arbeitet und man die Tabellen verbindet, würde auch z.b. das Löschen/Einfügen, Tabellen übergreifend funktionieren.
    Ist das eine Aussage oder eine Frage, bei der das Fragezeichen vergessen wurde?

    Egal - Jdfs um den Begriff "Löschweitergabe" zu klären:
    In allen relationalen Datenbanken kann man Löschweitergabe konfigurieren - leider oft nur mit Sql-Commands, weil brauchbare grafische Tools sind für viele Sql-Dialekte nicht verfügbar.
    Löschweitergabe bedeutet, dass wenn ein Datensatz gelöscht wird, dass dann automatisch alle Child-Datensätze mitgelöscht werden - die ansonsten eh nur Fehler produzieren würden, denn - um an dein Beispiel aus post#1 anzuknüpfen: Eine Bestellung (Child-Datensatz) ergibt keinen Sinn mehr, wenn der Kunde (Parent-Datensatz), der sie bestellt hat, in der Datenbank nicht (mehr) existiert.

    Löschweitergabe gehört untrennbar zum Konzept "Relation", und ist damit natürlich Kern-Feature relationaler Datenbanken (aber nicht nur, sondern das gilt für alle relationale Datenmodelle, ja sogar für hierarchische (nichtrelational)).
    Und natürlich wirkt Löschweitergabe immer über mehrere Tabellen - etwa von Kunde nach Bestellung - eben weil eine Relation immer 2 Tabellen betrifft - schon vom Wort her: "Relation": "Beziehung" - das ist immer etwas "dazwischen", und "dazwischen" ist schon vom Wort her immer zwischen Mehreren.
    Sorry, das war eine frage ;)

    Die "Löschweitergabe" funktioniert leider nicht mit der Aktuellen SQLite Version, man braucht eine ältere damit dieses geht. (Warum entfernt man diese Feature?!).
    Habe mir mal den SQL Server von Microsoft Installiert und auch mit den Desinger gearbeitet. Damit hat es nun geklappt.

    Das gemeine ist, wenn man in der Aktuellen SQLite Version das richtige SQL Command übergibt für die "Löschweitergabe" kommt keine Fehlermeldung.

    Vielen Dank für deine Unterstützung, ich werde mich wohl mal etwas Intensiver mit den ganzen SQL Commands beschäftigen. Das ja bald genau so umfangreich wie C# ;)
    Oh, das kann ich dir gerade nicht mehr genau sagen. Ich habe mich durch so viele Seiten gegoogelt und hatte das irgendwo gelesen.
    Mit M$SQL habe ich es sofort hinbekommen. Bei SQLite hingehen komme ich nicht weiter. Im Connection String habe ich auch "PRAGMA foreign_keys = ON;" stehen, aber bringt nichts.
    Habe es heraus gefunden.

    Beispiel für MySQL

    SQL-Abfrage

    1. CREATE TABLE `Kunden` ( `Kundennummer` INT NOT NULL, `Kundenname` VARCHAR(255) NOT NULL, PRIMARY KEY (`Kundennummer`));
    2. CREATE TABLE `Bestellung` ( `Kundennummer` INT NOT NULL, `Bezahlt` BOOLEAN NOT NULL, PRIMARY KEY (`Kundennummer`));
    3. ALTER TABLE `Bestellung` ADD CONSTRAINT `Kunden_fk0` FOREIGN KEY (`Kundennummer`) REFERENCES `Kunden`(`Kundennummer`) ON DELETE cascade;
    4. INSERT INTO testdb.kunden (Kundennummer, Kundenname) VALUES (1234, 'Musterman');
    5. INSERT INTO testdb.bestellung (Kundennummer, Bezahlt) VALUES ((SELECT Kundennummer FROM testdb.kunden WHERE Kundennummer=1234), 1);


    Beispiel für SQLite

    SQL-Abfrage

    1. CREATE TABLE `Kunden` ( `Kundennummer` INT NOT NULL, `Kundenname` VARCHAR(255) NOT NULL, PRIMARY KEY (`Kundennummer`));
    2. CREATE TABLE `Bestellung` ( `Kundennummer` INT NOT NULL, `Bezahlt` BOOLEAN NOT NULL, PRIMARY KEY (`Kundennummer`), FOREIGN KEY ('Kundennummer') REFERENCES Kunden('Kundennummer') ON DELETE CASCADE);
    3. INSERT INTO kunden (Kundennummer, Kundenname) VALUES (1234, 'Musterma');
    4. INSERT INTO bestellung (Kundennummer, Bezahlt) VALUES ((SELECT Kundennummer FROM kunden WHERE Kundennummer=1234), 1);


    Der Befehl "FOREIGN KEY" muss einfach anders angewendet werden in SQLite, nur dann funktionier es auch.
    Zusätzlich ist wichtig, das in SQLite im Connection-String "PRAGMA foreign_keys = ON;" mit drinnen ist.

    Wenn ich jetzt ein Delete auf die Kundennummer 1234 mache, wird auch der Eintrag in der Bestellung mit gelöscht.