wake-up-neo.com

Fremdschlüsseleinschränkungen in Android using SQLite? On Delete cascade

Ich habe zwei Tabellen: Tracks und Wegpunkte, ein Track kann viele Wegpunkte haben, aber ein Wegpunkt ist nur einem Track zugeordnet.

In der Wegpunktetabelle habe ich eine Spalte mit dem Namen "trackidfk", in die die track_ID eingefügt wird, sobald eine Spur erstellt wurde. Für diese Spalte habe ich jedoch keine Fremdschlüsseleinschränkungen festgelegt.

Wenn ich einen Track lösche, möchte ich die zugewiesenen Wegpunkte löschen. Ist dies möglich? Ich habe über die Verwendung von Triggern gelesen, glaube aber nicht, dass sie in Android unterstützt werden.

So erstellen Sie die Wegpunktetabelle:

public void onCreate(SQLiteDatabase db) {
    db.execSQL( "CREATE TABLE " + TABLE_NAME 
                + " (" 
                + _ID         + " INTEGER PRIMARY KEY AUTOINCREMENT, " 
                + LONGITUDE   + " INTEGER," 
                + LATITUDE    + " INTEGER," 
                + TIME        + " INTEGER,"
                + TRACK_ID_FK + " INTEGER"
                + " );"
              );

    ...
}
89
jcrowson

Fremdschlüsseleinschränkungen mit Löschkaskade werden unterstützt, müssen jedoch aktiviert werden.
Ich habe gerade das Folgende zu meinem SQLOpenHelper hinzugefügt, was den Trick zu tun scheint.

@Override
public void onOpen(SQLiteDatabase db) {
    super.onOpen(db);
    if (!db.isReadOnly()) {
        // Enable foreign key constraints
        db.execSQL("PRAGMA foreign_keys=ON;");
    }
}

Ich habe meine Referenzierungsspalte wie folgt deklariert.

mailbox_id INTEGER REFERENCES mailboxes ON DELETE CASCADE
234
Phil

Seit Android 4.1 (API 16) SQLiteDatabase unterstützt:

public void setForeignKeyConstraintsEnabled (boolean enable)
53
e.shishkin

Wie der Beitrag von e.shishkin ab API 16 besagt, sollten Sie Fremdschlüsseleinschränkungen in der SqLiteOpenHelper.onConfigure(SqLiteDatabase) -Methode mithilfe der db.setForeignKeyConstraintsEnabled(boolean) aktivieren.

@Override
public void onConfigure(SQLiteDatabase db){
    db.setForeignKeyConstraintsEnabled(true);
}
26
malcolm

Nie zu alt für eine Antwort mit einer vollständigeren Antwort.

@Override public void onOpen(SQLiteDatabase db) {
    super.onOpen(db);
    if (!db.isReadOnly()) {
        setForeignKeyConstraintsEnabled(db);
    }
    mOpenHelperCallbacks.onOpen(mContext, db);
}

private void setForeignKeyConstraintsEnabled(SQLiteDatabase db) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
        setForeignKeyConstraintsEnabledPreJellyBean(db);
    } else {
        setForeignKeyConstraintsEnabledPostJellyBean(db);
    }
}

private void setForeignKeyConstraintsEnabledPreJellyBean(SQLiteDatabase db) {
    db.execSQL("PRAGMA foreign_keys=ON;");
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void setForeignKeyConstraintsEnabledPostJellyBean(SQLiteDatabase db) {
    db.setForeignKeyConstraintsEnabled(true);
}
9
Codeversed

Was auch immer @phil erwähnt ist gut. Sie können jedoch eine andere Standardmethode verwenden, die in der Datenbank selbst verfügbar ist, um den Fremdschlüssel festzulegen. Das ist setForeignKeyConstraintsEnabled (true).

@Override
public void onOpen(SQLiteDatabase db) {
    super.onOpen(db);
    if (!db.isReadOnly()) {
        // Enable foreign key constraints
        db.execSQL("PRAGMA foreign_keys=ON;"); 
              //(OR)
        db.setForeignKeyConstraintsEnabled (true)
    }
}

Für Dokumente siehe SQLiteDatabase.setForeignKeyConstraintsEnabled

6
anand krish

Trigger werden von Android und diese Art des Kaskadenlöschens wird von sqlite nicht unterstützt. Ein Beispiel für die Verwendung von Triggern auf Android findet sich hier) . Obwohl die Verwendung von Transaktionen wie von Thorsten angegeben wahrscheinlich genauso einfach ist wie ein Auslöser.

4
Dave.B

Ich glaube nicht, dass SQLite dies standardmäßig unterstützt. Was ich in meinen Apps mache, ist:

  1. Transaktion erstellen
  2. Detaildaten löschen (Wegpunkte in Ihrem Beispiel)
  3. Stammdaten löschen (Tracks in Ihrem Beispiel)
  4. Transaktion bei Erfolg festschreiben

Auf diese Weise bin ich sicher, dass entweder alle Daten gelöscht werden oder keine.

4

SQLite-Version in Android 1.6 ist 3.5.9, unterstützt also keine Fremdschlüssel ...

http://www.sqlite.org/foreignkeys.html "Dieses Dokument beschreibt die Unterstützung für SQL-Fremdschlüsseleinschränkungen, die in SQLite Version 3.6.19 eingeführt wurden."

In Froyo ist es SQLite Version 3.6.22, also ...

BEARBEITEN: um die SQLite-Version zu sehen: adb Shell sqlite3 -version

3
GBouerat

Fremdschlüssel mit "on delete cascade" werden in SQLite ab Android 2.2) unterstützt. Seien Sie jedoch vorsichtig, wenn Sie diese verwenden: Manchmal wird ein Fehler beim Starten eines Fremdschlüssels in einer Spalte gemeldet, aber Das eigentliche Problem liegt entweder in einer anderen Fremdschlüsseleinschränkung in der untergeordneten Tabelle oder in einer anderen Tabelle, die auf diese Tabelle verweist.

Es sieht so aus, als ob SQLite alle Einschränkungen überprüft, wenn es eine davon startet. Es wird tatsächlich in der Dokumentation erwähnt. DDL versus DML Constraint Checks.

1
Yar