我有两个表:轨道和航点,轨道可以有多个航点,但航点只分配给一个航迹。
在点数表中,我有一个名为“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"
+ " );"
);
...
}
答案 0 :(得分:232)
支持使用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
答案 1 :(得分:53)
由于Android 4.1(API 16)SQLiteDatabase支持:
public void setForeignKeyConstraintsEnabled (boolean enable)
答案 2 :(得分:26)
正如e.shishkin的帖子从API 16开始说的那样,您应该使用SqLiteOpenHelper.onConfigure(SqLiteDatabase)
db.setForeignKeyConstraintsEnabled(boolean)
方法中启用外键约束
@Override
public void onConfigure(SQLiteDatabase db){
db.setForeignKeyConstraintsEnabled(true);
}
答案 3 :(得分: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);
}
答案 4 :(得分:6)
无论@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)
}
}
答案 5 :(得分:4)
我认为SQLite不支持开箱即用。我在我的应用程序中所做的是:
这样我确定所有数据都被删除或没有。
答案 6 :(得分:4)
android支持触发器,sqlite不支持该类型的级联删除。可以在here找到在android上使用触发器的示例。虽然像Thorsten所说的那样使用交易可能就像触发一样容易。
答案 7 :(得分:3)
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
答案 8 :(得分:1)
Android 2.2及更高版本的SQLite支持带有“on delete cascade”的外键。但是在使用它们时要小心:有时在一列上触发一个外键时会报告错误,但真正的问题在于子表中的另一个列外键约束,或者其他一些表引用该表。
看起来SQLite在启动其中一个时检查所有约束。它实际上在文档中提到过。 DDL与DML约束检查。
答案 9 :(得分:0)
如果您使用的是Android Room,请执行以下操作。
Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME)
.addCallback(object : RoomDatabase.Callback() {
// Called when the database has been opened.
override fun onOpen(db: SupportSQLiteDatabase) {
super.onOpen(db)
//True to enable foreign key constraints
db.setForeignKeyConstraintsEnabled(true)
}
// Called when the database is created for the first time.
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
}
}).build()