当前位置:  开发笔记 > 编程语言 > 正文

Android中使用SQLite的外键约束?在删除级联

如何解决《Android中使用SQLite的外键约束?在删除级联》经验,为你挑选了5个好方法。

我有两个表:轨道和航点,一个轨道可以有很多航点,但一个航点只分配给一个轨道.

在点数表中,我有一个名为"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"
                + " );"
              );

    ...
}

Phil.. 236

支持使用on delete cascade的外键约束,但您需要启用它们.
我刚刚将以下内容添加到我的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

这意味着它只适用于Android 2.2 Froyo,它有SQLite 3.6.22 (58认同)

作为评论:这仅适用于sqlite版本3.6.19. (32认同)

Google建议在[`onConfigure()`](http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#onConfigure(android.database.sqlite.SQLiteDatabase))中编写`PRAGMA`语句,但它需要API级别16(Android 4.1),然后你可以简单地调用[`setForeignKeyConstraintsEnabled`](http://stackoverflow.com/a/12531927/1402846). (12认同)

@Phil,你为什么使用if-read-only条件? (2认同)


e.shishkin.. 53

由于Android 4.1(API 16)SQLiteDatabase支持:

public void setForeignKeyConstraintsEnabled (boolean enable)


小智.. 26

正如e.shishkin的帖子从API 16开始说的那样,你应该在SqLiteOpenHelper.onConfigure(SqLiteDatabase)方法中启用外键约束db.setForeignKeyConstraintsEnabled(boolean)

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


Codeversed.. 9

用更完整的答案回答问题永远不会过于陈旧.

@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);
}


anand krish.. 6

无论@phil提到什么都是好的.但您可以使用Database自身中可用的另一种默认方法来设置外键.那就是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)
    }
}

对于Docs,请参阅SQLiteDatabase.setForeignKeyConstraintsEnabled



1> Phil..:

支持使用on delete cascade的外键约束,但您需要启用它们.
我刚刚将以下内容添加到我的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


这意味着它只适用于Android 2.2 Froyo,它有SQLite 3.6.22
作为评论:这仅适用于sqlite版本3.6.19.
Google建议在[`onConfigure()`](http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#onConfigure(android.database.sqlite.SQLiteDatabase))中编写`PRAGMA`语句,但它需要API级别16(Android 4.1),然后你可以简单地调用[`setForeignKeyConstraintsEnabled`](http://stackoverflow.com/a/12531927/1402846).
@Phil,你为什么使用if-read-only条件?

2> e.shishkin..:

由于Android 4.1(API 16)SQLiteDatabase支持:

public void setForeignKeyConstraintsEnabled (boolean enable)



3> 小智..:

正如e.shishkin的帖子从API 16开始说的那样,你应该在SqLiteOpenHelper.onConfigure(SqLiteDatabase)方法中启用外键约束db.setForeignKeyConstraintsEnabled(boolean)

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



4> Codeversed..:

用更完整的答案回答问题永远不会过于陈旧.

@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);
}



5> anand krish..:

无论@phil提到什么都是好的.但您可以使用Database自身中可用的另一种默认方法来设置外键.那就是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)
    }
}

对于Docs,请参阅SQLiteDatabase.setForeignKeyConstraintsEnabled


您发布的文档建议:`调用此方法的好时机是在调用openOrCreateDatabase(File,SQLiteDatabase.CursorFactory)或onConfigure(SQLiteDatabase)回调之后.因此,而不是`onOpen`,`onConfigure`似乎是正确的地点.
推荐阅读
郑谊099_448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有