Ограничения внешнего ключа в Android с помощью SQLite? on Удалить каскад
У меня есть две таблицы: дорожки и путевые точки, трек может иметь много путевых точек, но путевая точка назначается только одному треку.
В том, что касается таблицы точек, у меня есть столбец с названием «trackidfk», который вставляет track_ID после создания трека, однако я не устанавливаю ограничения внешнего ключа в этом столбце.
Когда я удаляю трек, я хочу удалить назначенные путевые точки, возможно ли это ?. Я читал об использовании триггеров, но я не думаю, что они поддерживаются в Android.
- Android Как нарисовать гладкую линию после пальца
- Как я могу разобрать этот JSON в Android?
- Проверьте ориентацию на телефоне Android
- Как сместить ActionBar вместе с NavigationDrawer
- Почему значение 09 слишком велико для целого числа?
Чтобы создать таблицу путевых точек:
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" + " );" ); ... }
- Android RecyclerView добавление и удаление элементов
- SSLHandshakeException Цепочный якорь для пути сертификации не найден Android HTTPS
- Java Runtime.exec ()
- Android - ImageLoader должен быть init с настройкой перед использованием в UIL
- Предотвратить показ веб-страницы «веб-страница недоступна»
- Лучший способ сравнить даты в Android
- Как найти программные приложения, запущенные в настоящее время, в Android?
- Ошибка: java: javacTask: исходный выпуск 8 требует целевого релиза 1.8
Поддерживаются ограничения внешнего ключа с помощью каскада delete, но вам необходимо включить их.
Я просто добавил следующее в свой 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 4.1 (API 16) SQLiteDatabase поддерживает:
public void setForeignKeyConstraintsEnabled (boolean enable)
Как говорится в сообщении от e.shishkin из API 16 up, вы должны включить ограничения внешнего ключа в 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, это хорошо. Но вы можете использовать другой метод по умолчанию, ansible в самой базе данных, для установки внешнего ключа. Это 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
Я не думаю, что SQLite поддерживает это из коробки. Что я делаю в своих приложениях:
- Создать транзакцию
- Удалить подробные данные (путевые точки в вашем примере)
- Удалить core data (дорожки в вашем примере)
- Зафиксировать транзакцию с успехом
Таким образом, я уверен, что либо все данные удалены, либо нет.
Триггеры поддерживаются андроидом, и этот тип каскадного удаления не поддерживается sqlite. Пример использования триггеров для Android можно найти здесь . Хотя использование транзакций, как сказал Торстен, возможно, так же просто, как триггер.
Версия SQLite в android 1.6 – 3.5.9, поэтому она не поддерживает foreign keys …
http://www.sqlite.org/foreignkeys.html “В этом документе описывается поддержка ограничений внешнего ключа SQL, введенных в SQLite версии 3.6.19.”
В Froyo это SQLite версии 3.6.22, поэтому …
EDIT: посмотреть версию sqlite: adb shell sqlite3 -version
Внешние ключи с “on delete cascade” поддерживаются в SQLite в Android 2.2 и выше. Но будьте осторожны при их использовании: иногда возникает ошибка при запуске одного внешнего ключа в одном столбце, но реальная проблема заключается в любом другом внешнем ключевом ограничении в дочерней таблице, или какая-либо другая таблица тета ссылается на эту таблицу.
Похоже, SQLite проверяет все ограничения при запуске одного из них. Это фактически упоминается в документации. Проверки ограничений DDL и DML.