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

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

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

+ " );"

);

...

}

9个解决方案

232 votes

支持使用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

Phil answered 2019-09-08T20:56:45Z

53 votes

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

public void setForeignKeyConstraintsEnabled (boolean enable)

e.shishkin answered 2019-09-08T20:57:08Z

26 votes

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

@Override

public void onConfigure(SQLiteDatabase db){

db.setForeignKeyConstraintsEnabled(true);

}

malcolm answered 2019-09-08T20:57:32Z

9 votes

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

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

}

Codeversed answered 2019-09-08T20:57:56Z

6 votes

无论@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)

}

}

对于Docs,请参阅SQLiteDatabase.setForeignKeyConstraintsEnabled

anand krish answered 2019-09-08T20:58:26Z

4 votes

我不认为SQLite支持开箱即用。 我在我的应用程序中所做的是:

创建交易

删除详细数据(示例中的航点)

删除主数据(示例中的轨道)

提交成功交易

这样我确定所有数据都被删除或没有。

Thorsten Dittmar answered 2019-09-08T20:59:22Z

4 votes

android支持触发器,sqlite不支持这种类型的级联删除。 可以在此处找到在android上使用触发器的示例。 尽管像Thorsten所说的那样使用交易可能就像触发器一样容易。

Dave.B answered 2019-09-08T20:59:46Z

3 votes

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

GBouerat answered 2019-09-08T21:00:29Z

1 votes

在Android 2.2及更高版本的SQLite中支持具有“on delete cascade”的外键。 但是在使用它们时要小心:有时在一列上触发一个外键时会报告错误,但真正的问题在于子表中的另一个列外键约束,或者其他一些表引用该表。

看起来SQLite在启动其中一个时会检查所有约束。 它实际上在文档中提到过。 DDL与DML约束检查。

Yar answered 2019-09-08T21:00:59Z

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐