1. Nimm jetzt an unserem Uhans - 3. ADVENT - Gewinnspiel teil - Alle Informationen findest Du hier!

Frage zu Fremdschlüsseln

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von Micka, 21.06.2012.

  1. Micka, 21.06.2012 #1
    Micka

    Micka Threadstarter Erfahrener Benutzer

    Beiträge:
    173
    Erhaltene Danke:
    1
    Registriert seit:
    30.12.2011
    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?
     
  2. Tom299, 21.06.2012 #2
    Tom299

    Tom299 Android-Experte

    Beiträge:
    602
    Erhaltene Danke:
    120
    Registriert seit:
    31.08.2011
    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.
     
  3. Micka, 21.06.2012 #3
    Micka

    Micka Threadstarter Erfahrener Benutzer

    Beiträge:
    173
    Erhaltene Danke:
    1
    Registriert seit:
    30.12.2011
    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.
     
  4. Tom299, 21.06.2012 #4
    Tom299

    Tom299 Android-Experte

    Beiträge:
    602
    Erhaltene Danke:
    120
    Registriert seit:
    31.08.2011
    Achso, du machst das andersrum, verstehe. Ich verlasse mich da lieber auf mich selbst und lösche die Abhängigkeiten manuell ;-)
     
  5. swordi, 21.06.2012 #5
    swordi

    swordi Gewerbliches Mitglied

    Beiträge:
    3,389
    Erhaltene Danke:
    441
    Registriert seit:
    09.05.2009
    kann es sein, dass du ein

    beim ersten app start ausführen musst ?

    das ganze heißt "Referenzielle Integrität".
     
  6. Tom299, 21.06.2012 #6
    Tom299

    Tom299 Android-Experte

    Beiträge:
    602
    Erhaltene Danke:
    120
    Registriert seit:
    31.08.2011
    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
     
  7. TheDarkRose, 21.06.2012 #7
    TheDarkRose

    TheDarkRose Gewerbliches Mitglied

    Beiträge:
    1,292
    Erhaltene Danke:
    136
    Registriert seit:
    20.08.2010
    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
     
  8. swordi, 21.06.2012 #8
    swordi

    swordi Gewerbliches Mitglied

    Beiträge:
    3,389
    Erhaltene Danke:
    441
    Registriert seit:
    09.05.2009
  9. Sentenza, 21.06.2012 #9
    Sentenza

    Sentenza Erfahrener Benutzer

    Beiträge:
    224
    Erhaltene Danke:
    65
    Registriert seit:
    15.08.2011
    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 ^^
     
  10. Micka, 21.06.2012 #10
    Micka

    Micka Threadstarter Erfahrener Benutzer

    Beiträge:
    173
    Erhaltene Danke:
    1
    Registriert seit:
    30.12.2011
    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
     
  11. TheDarkRose, 21.06.2012 #11
    TheDarkRose

    TheDarkRose Gewerbliches Mitglied

    Beiträge:
    1,292
    Erhaltene Danke:
    136
    Registriert seit:
    20.08.2010
    Zusammengefasst: PRAGMA muss aktiviert sein und ON UPDATE bzw ON DELETE muss beim erstellen des FOREIGN KEYS angegeben werden.
     
  12. Tom299, 22.06.2012 #12
    Tom299

    Tom299 Android-Experte

    Beiträge:
    602
    Erhaltene Danke:
    120
    Registriert seit:
    31.08.2011
    dann würd mir die version mit dem trigger am besten gefallen, ist ja dann auch dynamisch ;-)
     

Diese Seite empfehlen