какой оператор sqlite может выдать результат для указания повторяющихся записей? Android - PullRequest
2 голосов
/ 28 октября 2009

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

Первый способ:

db.execSQL("INSERT INTO " + DatabaseHelper.DATABASE_TABLE + 
"(LATITUDE, LONGITUDE, RATING) SELECT " + latitude + ", " + longitude + ", " + rating +
" WHERE NOT EXISTS (SELECT 1 FROM " + DatabaseHelper.DATABASE_TABLE +
" WHERE LATITUDE = " + latitude + " AND LONGITUDE = " + longitude + ")");

Второй способ:

    long id = -1;
    try {
        id = db.compileStatement(
                "SELECT COUNT(*) FROM " + DatabaseHelper.DATABASE_TABLE
                        + " WHERE LATITUDE = " + latitude
                        + " AND LONGITUDE = " + longitude)
                .simpleQueryForLong();
    } catch (NullPointerException e) {
        return -1;
    }
    return id;

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

Второй способ, возвращает фактическое количество строк, которые соответствуют номерам, которые я хочу сохранить, если число вернулось больше 1, запросить у пользователя сообщение «значения существуют».

Я ходил взад и вперёд, пробуя разные способы, но я не знаю, как настроить SQLite для создания УНИКАЛЬНЫХ пар, что, как мне сказали, будет самым простым. Если кто-то сможет исправить любой из этих способов и / или прокомментировать их, это будет с благодарностью.

Спасибо

Ответы [ 3 ]

3 голосов
/ 28 октября 2009

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

Если правильно, вы хотите объявить ПЕРВИЧНЫЙ или УНИКАЛЬНЫЙ КЛЮЧ, который включает столбцы широту и долготу. Если вы сделаете это, то любая попытка ВСТАВИТЬ ту же пару вызовет исключение, которое вы можете перехватить и тем самым уведомить пользователя. Используя эту технику, вам не нужно будет использовать в своем запросе предложение WHERE NOT EXISTS (...), просто сделайте простой INSERT и позвольте SQLite предупредить вас о нарушении ограничения UNIQUEness.

Если ваша таблица уже существует, ключ проще всего добавить с помощью команды SQL CREATE INDEX . Поскольку у вас может быть только один ПЕРВИЧНЫЙ КЛЮЧ на любом столе, если у вас уже есть ПЕРВИЧНЫЙ КЛЮЧ на столе, для этой цели вам потребуется использовать УНИКАЛЬНЫЙ КЛЮЧ.

Простейшая форма оператора CREATE INDEX, которую вы бы использовали:

CREATE UNIQUE INDEX lat_long_unique ON Database_Table(latitude, longitude)
1 голос
/ 28 октября 2009

Мне кажется, что использование raw lat / long не лучший способ проверить наличие дубликатов. Каждая возможная комбинация широта / долгота в формате Android GeoPoint 1E6 охватывает область размером менее пяти квадратных дюймов. Этот размер, конечно, различается в зависимости от того, где на Земле вы стоите, но это довольно хорошее эмпирическое правило. Таким образом, вы должны, по крайней мере, округлить свой лат / лонг до ближайших десяти, сотен или тысяч в зависимости от размера того, что вы хотите измерить.

Перед сохранением в базе данных:

lat = (lat/1000)*1000; 
lon = (lon/1000)*1000;

Вот хороший инструмент для расчета расстояний между широтами / точками на Земле:

http://jan.ucc.nau.edu/~cvm/latlongdist.html

0 голосов
/ 02 февраля 2010

Я решил использовать свой второй подход (см. Выше)

Причина, по которой после создания UNIQUE INDEX, похоже, не работает для меня и оказалась для меня трудной задачей, чтобы решить,был результатом конца моего или SQLite.

Его цель не тривиальна, подход может быть элементарным, но он делает то, что мне нужно.

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

...