Схема базы данных SQLite изменила ошибку в Content Provider

Я использую Content Providers и Sync Adapters для процедуры синхронизации.

Моя процедура получает JSONObject и вставляет или обновляет запись.

Чтобы решить, будем ли мы обновлять или вставлять, мы проверяем, существует ли запись в базе данных. Здесь возникает ошибка sqlite.

06-03 10:58:21.239: INFO/Database(340): sqlite returned: error code = 17, msg = prepared statement aborts at 45: [SELECT * FROM table WHERE (id = ?) ORDER BY id]

Я провел небольшое исследование и нашел эту дискуссию по этому вопросу. Из этого обсуждения я понял, что sqlite_exec() нужно вызывать. Как мне реализовать это в контент-провайдере?

Изменить

Вставить/обновить чек

// Update or Insert
ContentValues cv = new ContentValues();
/* put info from json into cv */
if(mContentResolver.update(ClientsProvider.CONTENT_URI, cv, null, null) == 0) {
    // add remote id of entry
    cv.put("rid", o.optInt("id"));
    mContentResolver.insert(ClientsProvider.CONTENT_URI, cv);
}

КонтентПровайдер::обновить

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    int count = 0;
    switch(uriMatcher.match(uri)) {
    case CLIENTS:
        count = clientDB.update(TABLE_NAME, values, selection, selectionArgs);
        break;
    case CLIENT_ID:
        count = clientDB.update(TABLE_NAME, values, ID + " = " + uri.getPathSegments().get(0) + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);
        break;
    default:
        count = 0;
    }
    return count;
}

person Pim Reijersen    schedule 03.06.2011    source источник
comment
выполните db.update... если возвращает 0, то все равно выполните db.insert... взгляните на esilo.pl /ListSynSample.zip как я вижу, вы создаете что-то похожее   -  person Selvin    schedule 03.06.2011
comment
Спасибо за предложение, но оно не устраняет ошибку. Теперь он выдает ту же ошибку, но о операторе вставки.   -  person Pim Reijersen    schedule 03.06.2011
comment
Нет, я использую ContentProviders. Я могу представить реализацию Transaction в методе applyBatch(..) ContentProvider, но пока это не вариант, потому что результат запроса проверяется, чтобы решить, нужно ли нам запускать другой запрос.   -  person Pim Reijersen    schedule 03.06.2011
comment
в моем примере я использую прямые операции с базой данных как в contentprovider, так и в syncadapter. поэтому syncadapter не использует contentprovider для вставки/обновления данных в db, он только сообщает contentprovider, что данные в каком-то uri были изменены   -  person Selvin    schedule 03.06.2011
comment
Почему ты так поступил? Не могу придумать никаких причин, чтобы не использовать Content Provider. (если это не решит ошибку 17)   -  person Pim Reijersen    schedule 03.06.2011
comment
чтобы опустить абстракцию контент-провайдера... этот пример представляет собой пример синхронизации между устройством Android и удаленным сервером mssql через MS SyncFx 4.0... при обновлении/вставке устройства с использованием контент-провайдера в этой реализации я устанавливаю изменения, сделанные на устройстве, а затем синкадаптер синхронизирует эти изменения на удаленную БД. если я загружаю данные с сервера, все, что мне нужно, это просто вставить/обновить изменения, не устанавливая их как грязные в базе данных устройства...   -  person Selvin    schedule 03.06.2011
comment
в любом случае, трудно сказать, что именно вызывает эту ошибку, без какой-либо части вашего кода... поэтому, как я уже говорил, старайтесь не открывать курсор для проверки существования записи... если у вас есть базовая база данных с основным ключом... если нет строки с этим pk, он вернет 0 (db.update не cp.update в реализации cp вы можете вернуть null, если базовый db.update возвращает 0 и проверяет нуль) ... тогда вы должны вставить ... без наличие любого курсора (я предполагаю, что у вас есть 1 для проверки того, находится ли строка уже в БД) открыта   -  person Selvin    schedule 03.06.2011
comment
Добавлена ​​часть обновления/вставки в вопрос. Функция обновления вернет количество строк, измененных запросом на обновление.   -  person Pim Reijersen    schedule 03.06.2011
comment
Я получаю сообщение об ошибке 17 для самого первого (а иногда и второго) SELECT * после удаления всех таблиц и воссоздания данных.   -  person Someone Somewhere    schedule 11.06.2011


Ответы (1)


Проблема решена. Я не уверен, почему, но после очистки изображения эмулятора все работает именно так, как должно. Спасибо, что уделили время, Селвин!

person Pim Reijersen    schedule 03.06.2011
comment
sqlite вернул: код ошибки = 17 появляется у меня, когда я делаю [SELECT * FROM mytable]. Однако команда SELECT возвращает данные. Это похоже на ложное сообщение об ошибке, потому что это происходит при первом или втором SELECT * после того, как я заполнил базу данных SQLite данными. - person Someone Somewhere; 11.06.2011