В настоящее время я использую следующую инструкцию для создания таблицы в базе данных SQLite на устройстве Android.
CREATE TABLE IF NOT EXISTS 'locations' (
'_id' INTEGER PRIMARY KEY AUTOINCREMENT, 'name' TEXT,
'latitude' REAL, 'longitude' REAL,
UNIQUE ( 'latitude', 'longitude' )
ON CONFLICT REPLACE );
Предложение конфликта -в конце приводит к тому, что строки удаляются при выполнении новых вставок с теми же координатами. Документация SQLite содержит дополнительную информацию о предложении конфликта -.
Вместо этого я хотел бы сохранить прежние строки и просто обновить их столбцы. Каков наиболее эффективный способ сделать это в среде Android/SQLite?
CREATE TABLE
.INSERT
.ContentProvider#insert
.Я бы подумал, что более эффективно обрабатывать такие конфликты в базе данных. Кроме того, мне трудно переписать метод ContentProvider#insert
для рассмотрения сценария вставки -обновления .Вот код метода insert
:
public Uri insert(Uri uri, ContentValues values) {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
long id = db.insert(DatabaseProperties.TABLE_NAME, null, values);
return ContentUris.withAppendedId(uri, id);
}
Когда данные поступают из серверной части, все, что я делаю, это вставляю данные следующим образом.
getContentResolver.insert(CustomContract.Locations.CONTENT_URI, contentValues);
У меня проблемы с выяснением того, как применить здесь альтернативный вызов ContentProvider#update
. Кроме того, это не мое любимое решение в любом случае.
Изменить:
@CommonsWare :Я попытался реализовать ваше предложение по использованию INSERT OR REPLACE
. Я придумал этот уродливый кусок кода.
private static long insertOrReplace(SQLiteDatabase db, ContentValues values, String tableName) {
final String COMMA_SPACE = ", ";
StringBuilder columnsBuilder = new StringBuilder();
StringBuilder placeholdersBuilder = new StringBuilder();
List
Однако, когда я проверяю базу данных SQLite, равные столбцы по-прежнему удаляются и вставляются с новыми идентификаторами . Я не понимаю, почему это происходит, и думал, что причина в моей конфликтной -статье. Но документация утверждает обратное.
The algorithm specified in the OR clause of an INSERT or UPDATE overrides any algorithm specified in a CREATE TABLE. If no algorithm is specified anywhere, the ABORT algorithm is used.
Другим недостатком этой попытки является то, что вы теряете значение идентификатора, возвращаемого оператором вставки. Чтобы компенсировать это, я наконец нашел возможность запросить last_insert_rowid
. Это объясняется в сообщениях dtmilano и swiz . Однако я не уверен, что это безопасно, поскольку между ними может произойти еще одна вставка.