Будьте Осторожны С Sqlitedatabase.inserts.

Ковыряясь с базами данных в Android, я столкнулся с очень неприятной вещью: методы SQLiteDatabase для вставки данных работают не совсем так, как написано в документации.

Задача была проста: вставить запись и получить ее ключ для использования в другой таблице.

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

Оказалось, что получить можно всё, кроме этого очень старого ключа.

Чтобы разобраться в этом, мне пришлось провести несколько экспериментов на кошках, но теперь кое-что стало яснее.

Для начала посмотрим, что обещает нам Android в SQLiteDatabase: вставлять() - самый простой метод. Должен вернуть только что вставленный ключ или -1, если что-то пошло не так.

вставитьOrThrow() — описание точно соответствует предыдущему, но добавлено, что метод выбрасывает SQLException. Судя по названию, вы можете ожидать, что вместо возврата -1 будет выброшено SQLException, но мы пока не уверены.

вставитьВиОнКонфликт() - это самое интересное.

Нам обещают, что метод вернет ключ новой записи ИЛИ ключ существующей записи, если для конфликтов использовался алгоритм IGNORE ИЛИ -1. Также запомним, что здесь ничего не сказано о SQLException. Теперь посмотрим, что происходит на практике.

Давайте создадим простую таблицу и попробуем задать для нее разные алгоритмы разрешения конфликтов (в том числе и ни одного).

Откат и аборт я не проверял — их поведение в этом случае, судя по всему, будет аналогично фейлу, а меня больше всего интересовал игнор.

Давайте вставим в таблицу несколько уникальных значений, а затем попробуем добавить конфликтующее.

Давайте посмотрим, как все эти методы обрабатывают конфликты.

Если алгоритм разрешения конфликтов не указан, простой метод Insert() возвращает -1 (как и было обещано), а методы InsertOrThrow() и InsertWithOnConflict() вызывают исключение SQLiteConstraintException. И если это верно для метода InsertOrThrow(), то от метода InsertWithOnConflict() можно ожидать -1. То же самое происходит и с алгоритмом «провал».

Алгоритм замены сработал нормально — все методы удалили старую запись, вставили новую и вернули ее ключ.

А вот с таким необходимым «игнором» получился полный облом.

Ни один метод не выдал ошибку (-1 или SQLiteConstraintException).

Все единогласно вернули какое-то число — предположительно ключ последней записи, вставленной в таблицу.

Конечно, это совсем не то, что нам обещали.

В общем, документации доверять нельзя.

Любой метод может либо вернуть самые неожиданные значения, либо выдать исключение.

Но желаемого результата добиться не удалось — ни один метод не смог вернуть ключ существующей записи в случае конфликта.

Теги: #Android #SQLite #Разработка для Android

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.