SQLiteDatabase: вставлять, только если значение не существует (не с помощью необработанной команды SQL)

Я знаю, что есть команда SQL, которая выглядит так: IF NOT EXISTS, но поскольку класс SQLiteDatabase Android имеет несколько хороших методов, мне было интересно, можно ли вставить значение, если оно не существует, с помощью метода.

В настоящее время я использую это, чтобы вставить String:

public long insertString(String key, String value) {
    ContentValues initialValues = new ContentValues();
    initialValues.put(key, value);
    return db.insert(DATABASE_TABLE, null, initialValues);
}

(db является экземпляром SQLiteDatabase.)

Пробовал метод insertOrThrow() вместо insert(), но похоже он делает то же самое, что и insert(). То есть, если значение уже находится в строке, оно вставляется снова, поэтому теперь в строке есть два значения с одинаковым значением.


person gosr    schedule 29.03.2013    source источник
comment
Почему бы вам не сделать свой ключ уникальным?   -  person Hoan Nguyen    schedule 29.03.2013
comment
Вы можете использовать библиотеку ORM. Я использовал ORMRoid, и вы можете выполнять ряд SQL-запросов с помощью методов. ormlite.com/sqlite_java_android_orm.shtml   -  person dannyroa    schedule 29.03.2013


Ответы (4)


SQLiteDatabase: вставлять, только если значение не существует (не с помощью необработанной команды SQL)

Поскольку вы не хотите использовать необработанные запросы, вы можете добиться этого перед вставкой, просто создайте некоторую функцию, которая будет проверять, находится ли значение уже в базе данных. Он может вернуть логическое значение (или int), и если он вернет false, вы выполните запрос на вставку.

Небольшой пример:

public int getCount() {
    Cursor c = null;
    try {
        db = Dbhelper.getReadableDatabase();
        String query = "select count(*) from TableName where name = ?";
        c = db.rawQuery(query, new String[] {name});
        if (c.moveToFirst()) {
            return c.getInt(0);
        }
        return 0;
    }
    finally {
        if (c != null) {
            c.close();
        }
        if (db != null) {
            db.close();
        }
    }
}

if (getCount() == 0) {
   //perform inserting
}

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

Это можно решить, используя соответствующие ограничения, которые не позволят вам вставлять дубликаты. Проверь это:

person Simon Dorociak    schedule 29.03.2013
comment
Насколько рекомендуется использовать ограничения, а не следовать вашему опубликованному коду о проверке перед вставкой? Я тестировал ограничения и заметил, что трассировка стека выводится на консоль о невозможности вставки из-за ограничения, повлияет ли это на что-нибудь? Приложение не вылетает и не замечает снижения производительности, просто интересно. - person JustADev; 26.09.2016
comment
В моем случае мне нужно вставить тысячи строк, и выполнение отдельного запроса для каждой отдельной строки не выглядит мудрым решением. - person Muhammad Saqib; 01.12.2019

Вы можете установить поведение CONFLICT_IGNORE для конфликта при вставке строки:

public long insertString(String key, String value) {
    ContentValues initialValues = new ContentValues();
    initialValues.put(key, value);
    return db.insertWithOnConflict(DATABASE_TABLE, null, initialValues, SQLiteDatabase.CONFLICT_IGNORE);
}

Но это зависит от ограничения. Есть больше вариантов поведения, если вам нужно в будущем.

person neworld    schedule 29.03.2013

Есть два основных способа сделать это:

  1. Запросите базу данных. Вручную проверьте, существуют ли данные, а затем добавьте их, если они не существуют.
  2. Используйте CONSTRAINTs. Определите схему SQL, чтобы разрешить только уникальные данные для этого столбца.

Первый подход проще, если вы хотите выполнять разные действия в разных обстоятельствах (или если вы еще не владеете SQL). Второй подход может выполняться с гораздо меньшим объемом ввода и может применяться повсеместно.

person Sam    schedule 29.03.2013

Решение не в Android Api, а в базе данных. если вы хотите убедиться, что вставляемая вами строка еще не присутствует в базе данных, есть два возможных решения.

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

  2. Вы можете создать второй метод (вызываемый после каждой вставки; это затратно), который проверяет наличие дубликатов в таблице и удаляет их.

Я бы пошел с подходом 1.

вот пример синтаксиса UNIQUE

create table tablename( col1 datatype, col2 datatype, col3 datatype, UNIQUE(col1));

удачи

person PK0513    schedule 29.03.2013