#java #android #sqlite
#java #Android #sqlite
Вопрос:
Пример базы данных SQLite:
** Я не создаю базу данных, это база данных закладок Android, к которой я получаю доступ с помощью contentproviders.
** из того, что я понимаю после некоторых поисков, SQLite не поддерживает ограничения внешнего ключа, но возможны триггеры — http://www.sqlite.org/cvstrac/wiki?p=ForeignKeyTriggers
Столбец ПАПКИ -> 0 = не папка (false), 1 = папка (true)
РОДИТЕЛЬСКИЙ столбец -> содержит идентификатор его папки
ID TITLE FOLDER PARENT
1 folder1 1 0
2 item1 0 1
3 item2 0 1
4 folder2 1 1
5 item1 0 4
6 item2 0 4
7 folder3 1 4
8 item1 0 7
9 item2 0 7
…и так далее
В моем приложении для Android я пытаюсь рекурсивно удалить элементы из базы данных SQLite. У меня есть идентификатор первой папки, и я хочу выполнить цикл, чтобы найти все ее внутренние элементы (больше папок и элементов).
Например, у меня есть ID = 1, поэтому я могу легко удалить идентификаторы 2 и 3, запросив запрос всех элементов, для которых их родительским является ID = 1, получить идентификаторы элементов, а затем удалить.
Проблема в том, что я не могу понять, как удалить ID = 4 и его внутренние элементы (item1, item2 и folder3), а затем внутренние элементы folder3.
Хотелось бы получить помощь в этом! пытался часами :
Спасибо!
Комментарии:
1. Как вы хотите (должны) решить проблему, в (одном) операторе SQL или в «Java»?
2. @home в Java (я изменю его позже с помощью какого-нибудь Android API, который я должен использовать).
Ответ №1:
Похоже, вы хотите использовать КАСКАД УДАЛЕНИЯ в своем «родительском» столбце. Таким образом, при удалении родительского элемента все папки и файлы, которые указывают его в качестве родительского, также будут удалены. Затем эти результаты будут «каскадироваться» через вашу базу данных.
Итак, вы бы создали свою таблицу следующим образом:
CREATE TABLE files (id PRIMARY KEY AUTOINCREMENT, title TEXT, folder INTEGER CHECK(FOLDER EQUALS 0 OR FOLDER = 1), parent REFERENCES id);
Вот и все. Теперь каждый раз, когда вы удаляете родительскую папку, все ее дочерние элементы будут удалены. Вам больше ничего не нужно делать.
PS Наличие логических атрибутов (например, столбца вашей папки в данном случае) обычно считается плохой практикой. В вашем случае было бы лучше иметь папки и файлы в разных таблицах, потому что это разные вещи. Это называется нормализацией. Тем не менее, я мог видеть, что выдвигается аргумент о том, что способ, которым вы сейчас настраиваете вещи, все еще в порядке, потому что технически папки — это просто файлы, для которых установлен специальный флаг. Тем не менее, вам все равно следует рассмотреть идею создания в разных таблицах.
Комментарии:
1. звучит как решение. Я действительно мог бы использовать пример того, как использовать это в запросе…
2. Удивительный ответ 🙂 проблема в том, что я не создаю таблицу, это таблица SQLite для Android (я обращаюсь к ней с помощью ContentProviders — managedQuery …). В любом случае, я могу использовать это при запросе базы данных?
3. О, таблица не ваша? Хм …. это решение тогда не будет работать для вас. Мне придется придумать что-нибудь еще.
Ответ №2:
Если в java, то что-то вроде этого, я думаю, такие функции, как findNextChildId
, не должны быть проблемой:
deleteFolderAndSub(int id){
int childId = findNextChildId(id);
//Let -1 be that there are no more children
while (childId!=-1){
if (checkIfFolder(childId)){
deleteFolderAndSub(childId);
//on exiting from above function folder should be empty so it can be deleted without problem
deleteEmptyFolder(id);
} else {
deleteitem(id);
}
//it should be while loop and we have to find another child inside the loop
childId = findNextChildId(id)
}
}
findNextChildId(int parentId){
Coursor yourCoursor;
while(yourCoursor.moveToNext()){
if (parentId==yourCoursor.getInt("PARENT")){
yourCoursor.getInt("ID");
}
}
}
Комментарии:
1. Тестирование вашего кода с некоторыми изменениями. может сработать. moveToFirst() и moveToNext() заменят findNextChildId
2. да, просто понял это, пока вы это писали 🙂 Отлично! это должно сработать после некоторых изменений. Спасибо!