Haftpflicht Blogger
Virtual Server von Host Europe

SQLite Foreign Key Definition wird ignoriert

| 3. Dezember 2013 | Ein Kommentar

SQLite LogoForeign-Key Deklaration wird nicht durchgesetzt

Vor der SQLite Version 3.6.19 konnte man im CREATE-Statement ein FOREIGN-Key Constraint eingeben, die Anwendung hat jedoch diese Randbedingung nur als Befehl akzeptiert und nicht durchgesetzt. D.h. bei einem INSERT mit einem unzulässigem Foreign-Key-Wert kam keine "Error: foreign key constraint failed" Fehlermeldung und der falsche INSERT ging glatt in die Datenbanktabelle!

Foreign-Key Support

Da ich die Version 3.7.11 von SQLite verwende (siehe Meldung, wenn man sqlite3 im Command-Fenster eingibt), war ich nicht schlecht verwundert, dass ich bei einem INSERT-Versuch mit einem absichtlich unzulässigem Wert, dieser Sang-und-Klanglos von der Datenbank geschluckt wurde.

Erst ein Blick in die SQLite-Doku zeigt, warum das so ist. Die FOREIGN-KEY Unterstützung ist defaultmäßig deaktiviert (aus Rückwärtskompatibilitätsgründen) und muss erst explizit aktiviert werden [1].

 

Weitere Fallstricke

  1. Leider kommt es noch schlimmer. Einmal mit dem PRAGMA Statement aktiviert, bleibt diese Einstellung NICHT erhalten, wenn man sqlite3 verlässt und wieder startet. Dieses Verhalten (Vergessen der PRAGMA-Einstellung) könne sich laut Online-Doku in der Zukunft ändern, aber man solle sich lieber nicht darauf verlassen [1].
  2. Der PRAGMA-Befehl muss für pro Datenbankverbindung getrennt abgesetzt werden.
  3. Sind mit einem INSERT-Befehl unzulässige Einträge erst einmal in die Tabelle geschrieben worden, so sind diese falschen Einträge in der Tabelle permanent abgespeichert. D.h. wenn man von extern eine Datenbank erhält, dann kann man sich nie darauf verlassen, dass die FOREIGN-KEY Felder der Tabelleneinträge in sich konsistent sind.
  4. Auch wenn man die obige Aktivierung vorgenommen hat, kann es trotzdem sein, dass SQLite diese nicht umsetzt, wenn sqlite mit SQLITE_OMIT_FOREIGN_KEY oder mit SQLITE_OMIT_TRIGGER compiliert wurde [1].
  5. Wenn SQLite nicht im autocommit-Modus ist, dann ist der FOREIGN_KEY Constraint auch wirkungslos.

Mein Fazit

Unter den obigen Gegebenheiten macht es meines Erachtens keinen Sinn, eine SQLite Datenbank mit Foreign-Keys anzulegen. Man sollte defensiv an die Datenbankprogrammierung gehen, sich überhaupt nicht auf SQLite-Mechanismen verlassen und von vorneherein die Einhaltung von Foreign-Key Relationsships programmseitig prüfen.

 

Links:

[1] SQLite.org:  Enabling Foreign Key Support

 

Stichworte: , ,

Kategorie: Android, SQL

Kommentare (1)

Trackback-URL | Kommentarfeed

  1. Manfred Roos Steven sagt:

    Hallo Manfred,

    erfreulicherweise hat Google auf diese SQLite-Unzulänglichkeiten reagiert: Seit Android 4.1 (API-Level 16) steht die vielversprechende Methode SQLiteDatabase.setForeignKeyConstraintsEnabled zur Verfügung,
    welche in der Callback-Methode SQLiteOpenHelper.onConfigure aufgerufen werden kann.
    Auszug aus der Online-Doku:

    public void onConfigure (SQLiteDatabase db)

    Called when the database connection is being configured, to enable features such as […] foreign key support. […]
    This method should only call methods that configure the parameters of the database connection, […], setForeignKeyConstraintsEnabled(boolean), […], or executing PRAGMA statements.

    Erster Test der Funktionalität dieser Methode verlief positiv. (Leider wird die Methode von den Support-Libraries noch nicht unterstützt, ist daher auf Android-2.x Devices nicht anwendbar.)

    Gruß
    Steven

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.