У меня есть две таблицы: треки и путевые точки, у трека может быть много путевых точек, но путевая точка назначается только одному треку.
В таблице точек пути у меня есть столбец с именем «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"
+ " );"
);
...
}
java
android
sqlite
foreign-keys
JCrowson
источник
источник
PRAGMA
операторы,onConfigure()
но для этого требуется уровень API 16 (Android 4.1), и к тому времени вы можете просто позвонитьsetForeignKeyConstraintsEnabled
.onCreate
/onDowngrade
/onUpgrade
, которые были раньшеonOpen
. См. Исходный код в Android 4.1.1 .Начиная с Android 4.1 (API 16) SQLiteDatabase поддерживает:
public void setForeignKeyConstraintsEnabled (boolean enable)
источник
Как говорится в сообщении от e.shishkin, начиная с API 16, вы должны включить ограничения внешнего ключа в
SqLiteOpenHelper.onConfigure(SqLiteDatabase)
методе, используяdb.setForeignKeyConstraintsEnabled(boolean)
@Override public void onConfigure(SQLiteDatabase db){ db.setForeignKeyConstraintsEnabled(true); }
источник
Никогда не бывает слишком старым вопросом, чтобы дать более полный ответ.
@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); }
источник
Все, что упомянул @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
источник
A good time to call this method is right after calling openOrCreateDatabase(File, SQLiteDatabase.CursorFactory) or in the onConfigure(SQLiteDatabase) callback.
Итак, вместоonOpen
,onConfigure
похоже, правильное место.Я не думаю, что SQLite поддерживает это из коробки. В своих приложениях я делаю следующее:
Таким образом, я уверен, что либо все данные будут удалены, либо нет.
источник
Триггеры поддерживаются Android, и этот тип каскадного удаления не поддерживается sqlite. Пример использования триггеров на android можно найти здесь . Хотя использование транзакций, как заявил Торстен, вероятно, так же просто, как триггер.
источник
Версия SQLite в android 1.6 - 3.5.9, поэтому внешние ключи не поддерживаются ...
http://www.sqlite.org/foreignkeys.html «В этом документе описывается поддержка ограничений внешнего ключа SQL, представленных в SQLite версии 3.6.19».
Во Froyo это SQLite версии 3.6.22, так что ...
РЕДАКТИРОВАТЬ: чтобы увидеть версию sqlite: adb shell sqlite3 -version
источник
Внешние ключи с «каскадом удаления» поддерживаются в SQLite в Android 2.2 и выше. Но будьте осторожны при их использовании: иногда при запуске одного внешнего ключа в одном столбце появляется сообщение об ошибке, но настоящая проблема заключается либо в ограничении внешнего ключа другого столбца в дочерней таблице, либо в какой-либо другой таблице, которая ссылается на эту таблицу.
Похоже, SQLite проверяет все ограничения при запуске одного из них. Это действительно упоминается в документации. DDL по сравнению с проверками ограничений DML.
источник
Если вы используете 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()
источник