web-dev-qa-db-ja.com

Androidカスケードの削除でSQLite?を使用する場合の外部キー制約

トラックとウェイポイントの2つのテーブルがあります。トラックには多くのウェイポイントを設定できますが、ウェイポイントは1つのトラックにのみ割り当てられます。

ウェイポイントテーブルには、「trackidfk」という列があり、トラックが作成されるとtrack_IDが挿入されますが、この列には外部キー制約が設定されていません。

トラックを削除するときに、割り当てられたウェイポイントを削除したいのですが、これは可能ですか?トリガーの使用について読みましたが、Androidでサポートされているとは思いません。

ウェイポイントテーブルを作成するには:

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

削除カスケードでの外部キー制約はサポートされていますが、有効にする必要があります。
次のコードをSQLOpenHelperに追加しました。これでうまくいくようです。

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

参照列を次のように宣言しました。

mailbox_id INTEGER REFERENCES mailboxes ON DELETE CASCADE
234
Phil

Android 4.1(API 16) SQLiteDatabase サポート:

public void setForeignKeyConstraintsEnabled (boolean enable)
53
e.shishkin

E.shishkinの投稿がAPI 16以降で述べているように、SqLiteOpenHelper.onConfigure(SqLiteDatabase)を使用してdb.setForeignKeyConstraintsEnabled(boolean)メソッドで外部キー制約を有効にする必要があります

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

より完全な答えで答えるには、決して古すぎる質問ではありません。

@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

@philが言及したものは何でも良いです。ただし、データベース自体で使用可能な別のデフォルトメソッドを使用して、外部キーを設定できます。それは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)
    }
}

ドキュメントについては SQLiteDatabase.setForeignKeyConstraintsEnabled を参照してください

6
anand krish

トリガーはAndroidでサポートされ、そのタイプのカスケード削除はsqliteではサポートされていません。Androidでトリガーを使用する例は こちら 。Thorstenが述べたようにトランザクションを使用することは、おそらくトリガーと同じくらい簡単です。

4
Dave.B

SQLiteはこれをすぐにサポートするとは思わない。私のアプリでやっていることは:

  1. トランザクションを作成
  2. 詳細データの削除(例ではウェイポイント)
  3. マスターデータを削除します(例ではトラック)
  4. 成功時にトランザクションをコミット

そうすれば、すべてのデータが削除されるか、まったく削除されないことを確信しています。

4

Android 1.6のSQLiteバージョンは3.5.9であるため、外部キーをサポートしていません...

http://www.sqlite.org/foreignkeys.html 「このドキュメントでは、SQLiteバージョン3.6.19で導入されたSQL外部キー制約のサポートについて説明しています。」

Froyoでは、SQLiteバージョン3.6.22なので、...

編集:sqliteバージョンを表示するには:adb Shell sqlite3 -version

3
GBouerat

「削除カスケード」の外部キーは、SQLiteではAndroid 2.2以降でサポートされています。ただし、使用する場合は注意してください。1つの列で1つの外部キーを起動すると実際の問題は、子テーブルの別の列の外部キー制約、またはこのテーブルを参照する他のテーブルにあります。

SQLiteは、いずれかの制約を起動するときにすべての制約をチェックするようです。実際にドキュメントに記載されています。 DDL対DML制約チェック。

1
Yar