Frage zu Fremdschlüsseln

Micka

Micka

Fortgeschrittenes Mitglied
1
Hy, meine App ist nun nach langer Zeit fertg und läuft auch. Allerdings gibt es dort ein kleines Schönheitsproblem.

zunächst einmal mein Tabellenaufbau:
Code:
Log.i("HaushaltsbuchDataManager","onCreate");        
        db.execSQL("CREATE TABLE " + EINTRAEGE_TABLE_NAME + " (" 
             + _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "  
             + DAY +" INTEGER, "
             + MONTH + " INTEGER, "
             + YEAR + " INTEGER, "
             + CATEGORY + " TEXT NOT NULL, "
             + AMOUNT + " INTEGER, "
             + LISTID + " INTEGER, " 
             + "FOREIGN KEY(" + LISTID + ") REFERENCES " + LISTEN_TABLE_NAME + "(" + _ID+ "));"
           );
        db.execSQL("CREATE TABLE " + LISTEN_TABLE_NAME + " (" 
               + _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "  
               + LISTENNAME +" TEXT NOT NULL, "
               + LISTENTYP + " TEXT NOT NULL);"
        );
Aus MySQL und OracleSQL kenne ich es so wenn ich nun eine Liste Lösche werden alle Einträge mit der ListID automatisch auch gelöscht weils ja ein Fremdschlüssel ist.

Beim löschen von Listen gehe ich daher wie folgt vor:
Code:
public void deleteListe(long listid)
    {
        Log.i("HaushaltsbuchDataManager","deleteListe");
        SQLiteDatabase db = this.getWritableDatabase();
        try
        {
            db.execSQL("DELETE FROM " + LISTEN_TABLE_NAME + " WHERE "+ Constants._ID + " = '" + listid + "';");
            Log.i("HaushaltsbuchDataManager","Die Liste mit der ID " + listid + " wurde gelöscht.");
        }catch(Exception esql)
        {
            Log.i("HaushaltsbuchDataManager","Fehler beim löschen der Liste: " + esql.toString());
        }
        db.close();
    }
Um das zu testen hab ich direkt nach dem löschen mal eine Select Abfrage gemacht und siehe da es bleibt immer ein einzelner Eintrag über. Also wenn eine Liste mit 10 Einträgen gelöscht wird bleibt ein Eintrag über, die Liste wird aber in der Tabelle gestrichen.

Meines Wissens nach darf das garnicht sein, weil bei Fremdschlüsseln ja immer ein Eintrag in der referenzierten Tabelle existieren muss oder?
 
Hmm, so richtig versteh ichs jetzt nicht ... wenn du alle Sätze mit der ListID löschen tust, dann sollte da keiner übrig bleiben. Ist der Satz vielleicht gelockt?

Die ListID selbst sollte man erst löschen können, wenn es keine abhängigen Einträge dazu mehr gibt. Ob das in SQLite so ist, hab ich noch nicht versucht.

Btw. zum Löschen nutz ich z.B. direkt das delete-Kommando von der SQLiteDB. Aber das andere sollte vermutlich auch klappen.
 
Tom299 schrieb:
Hmm, so richtig versteh ichs jetzt nicht ... wenn du alle Sätze mit der ListID löschen tust, dann sollte da keiner übrig bleiben. Ist der Satz vielleicht gelockt?

...

Es geht mir darum eben nicht durch die Tabelle Eintraege zu ratern und dort jede Zeile mit der LISTID zu löschen, wenn ich das machen würde könnte ich mir die Fremdschlüssel komplett sparen.

Bei MySQL und OracleSQL ist es so, lösche ich eine Zeile einer Tabelle, auf die ein Fremdschlüssel referenziert ist, werden automatisch alle Zeilen in allen Datenbanken gelöscht, wo dieser Fremdschlüssel verwendet wird.

Also wenn ich in der Tabelle Listen eine Liste Lösche, werden automatisch alle Einträge dieser Liste in der Tabelle Einträge gelöscht. Klappt ja auch fast, es werden alle bis auf eine Zeile in der Tabelle Eintraege automatisch gelöscht.
 
Achso, du machst das andersrum, verstehe. Ich verlasse mich da lieber auf mich selbst und lösche die Abhängigkeiten manuell ;-)
 
kann es sein, dass du ein

PRAGMA foreign_keys = ON;

beim ersten app start ausführen musst ?

das ganze heißt "Referenzielle Integrität".
 
Also ich hab das grad mal mit meiner PostgreSQL-DB versucht. Hab die Tabelle User angelegt (ID, Name und Vorname) und die Tabelle Adresse (ID, User_ID, Strasse, PLZ und Ort).

User_ID ist der Fremdschlüssel.

Wenn ich jetzt ein paar Datensätze anlege und danach in der Tabelle User einen User löschen will, obwohl es noch Datensätze dazu in der Tabelle Adresse gibt, dann bekomm ich eine Fehlermeldung. Da wird dann nicht einfach in der Tabelle Adresse gelöscht. Vielleicht kann man das auch noch einstellen, aber das schau ich mir morgen an, hab jetzt Feierabend :D
 
Kenne das Standardverhalten von sqlite nicht, aber generell gilt, man sollte sich nie auf das Standardverhalten einer DB verlassen, sondern immer beim FOREIGN KEY angeben was beim löschen oder updaten passieren soll. Siehe Fremdschlüssel-Beziehungen - Optionen
 
Hier steht auch was dazu
SQLite Foreign Key Support

Ich verwende in meinen Anwendungen bisher keine derartigen Statements, sondern lösche einfach alle Datensätze in einer Transaktion ^^
 
Ich habs auch manuell gemacht, aber laut Professorin ist dynamisch gefordert.

Der ursprüngliche Beitrag von 17:56 Uhr wurde um 17:57 Uhr ergänzt:

Werd mir das.mit dem Pragma ma angucken, danke
 
Zusammengefasst: PRAGMA muss aktiviert sein und ON UPDATE bzw ON DELETE muss beim erstellen des FOREIGN KEYS angegeben werden.
 
dann würd mir die version mit dem trigger am besten gefallen, ist ja dann auch dynamisch ;-)
 

Ähnliche Themen

A
Antworten
1
Aufrufe
584
swa00
swa00
SpeedySix
Antworten
13
Aufrufe
1.401
jogimuc
J
M
Antworten
2
Aufrufe
630
Mozart40
M
Zurück
Oben Unten