Как мне удалить связанные строки в SQLite с Android? - PullRequest
1 голос
/ 05 марта 2012

У меня установлена ​​очень простая таблица ссылок, мне нужно удалить строки из всех 3 таблиц

Таблица 1 - Назначение {assignment_id}

LinkTable - AssignmentTasks {assignment_id, task_id}

Таблица 2 - Задачи {task_id}

Я могу легко удалить задания и задачи назначения, поскольку у меня есть идентификатор, но у меня нет списка задач, связанных с этим назначением.

Я создал курсор, который возвращает все task_ids, связанные с назначением, но я не могу удалить их, пока записи в таблице ссылок ссылаются на них. (Я не думаю, что смогу, так как ограничение внешнего ключа должно остановить меня, удаляя строки, на которые есть ссылки в другом месте)

Нужно ли мне хранить список task_ids, удалять записи assignment_tasks, удалять запись о назначении, а затем повторять сохраненный список task_ids и удалять каждую задачу? или есть лучший способ сделать это?

Ответы [ 2 ]

1 голос
/ 05 марта 2012

Почему бы не выполнить запрос task_id на основе assignment_id, который вы намереваетесь удалить.

Вы можете оставить удаление связанных данных в базе данных, но это зависит от того, было ли определено каскадное действие onDelete при создании отношений.

Если вы собираетесь использовать cascade onDelete, насколько я знаю, вам нужно включить это на sqlite. Смотрите этот пост, как. Ограничения внешнего ключа в Android с использованием SQLite? при каскаде удаления

Вы можете использовать необработанный запрос. например

удалить из задач, в которых находится task_id (выберите task_id из назначений, где assignment_id = your_assignment_id_here)

Я бы также предложил использовать транзакцию для этого по двум причинам: а) чтобы вы могли выполнить откат в случае сбоя любого из ваших запросов. б) sqlite в целом лучше работает с транзакциями быстро, если у вас есть несколько запросов. Поэтому поместите все свои очереди на удаление для данного действия в транзакции.

Ссылка ниже для rawQuery: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#rawQuery(java.lang.String, java.lang.String [])

1 голос
/ 05 марта 2012

Или вы можете временно отключить проверку ограничения внешнего ключа:

pragma foreign_keys = off;

Но в этом не должно быть необходимости.

Другая проблема заключается в том, что в настоящее время это записано как отношение «многие ко многим». Это будет означать, что несколько назначений могут относиться к одной задаче. Вероятно, не удастся удалить задачу только потому, что одно из назначений, ссылающихся на нее, было удалено. Вместо этого вам необходимо убедиться, что на задачу больше не ссылаются, прежде чем удалять ее.

В качестве альтернативы, если вы действительно хотели, чтобы каждая задача принадлежала только одному назначению, вы можете настроить свою схему следующим образом:

CREATE TABLE Assignment (assignment_id int PRIMARY KEY);
CREATE TABLE Task (
    task_id int PRIMARY KEY,
    assignment_id int FOREIGN KEY REFERENCES Assignment ON DELETE CASCADE
);

Бит ON DELETE CASCADE приводит к удалению записи Задачи в случае удаления присвоения, к которому она относится. Конечно, это работает, только если включены ограничения внешнего ключа. Если назначение удаляется с помощью триггера или из-за какого-либо другого каскада, вам может потребоваться включить рекурсивные триггеры также с pragma recursive_triggers = on.

Другая возможность (если вы хотите сохранить исходную схему) состоит в том, чтобы ссылки внешнего ключа в таблице AssignmentTask выполняли каскадное удаление. Таким образом, эти строки удаляются автоматически при удалении задач. Затем вы можете удалить Назначение, как только об этом позаботятся.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...