Android SQLiteException: нет такого столбца в пользовательских ромах

На устройствах с модифицированными версиями Android я получаю эту ошибку. Например, на устройствах Xiaomi.

String query = "select * from dialogues where userId = ? and topChat = 0 order by updatedAtByClient desc";
Cursor dialogRes = db.rawQuery(query, new String[]{userId});

Здесь я получаю исключение:

android.database.sqlite.SQLiteException: no such column: topChat (code 1):,
while compiling: select * from dialogues where userId = ? and topChat = 0 
order by updatedAtByClient desc

Я написал сообщение об исключении вручную, потому что пользователь прислал мне его на скриншоте, поэтому могут быть опечатки.

Как это можно исправить и почему это происходит?

UPD1: оператор создания таблицы выглядит примерно так:

"CREATE TABLE IF NOT EXISTS dialogues(fieldName VARCHAR, camelCaseFieldName VARCHAR,
topChat INTEGER, createdAt DATE);";

И у меня есть правильно реализованный метод обновления при изменении структуры БД, но эта конкретная таблица и имя поля не менялись долгое время.

UPD2: я сделал apk для пользователя с проблемами, который регистрирует эти столбцы таблицы, и я вижу проблемный столбец в журнале, и пользователь говорит, что эта версия работает нормально.

Так что кажется, что эта ошибка не происходит в 100% случаев. Очень странный. Может есть способ проверить базу на целостность после ее создания, и пересоздать таблицы с ошибками?


person lxknvlk    schedule 02.02.2019    source источник
comment
Можете ли вы показать нам заявление CREATE TABLE? Также, возможно, стоит предоставить этому пользователю версию, которая может перечислять столбцы таблицы, чтобы вы могли видеть, как таблица создается на устройстве.   -  person Michael Dodd    schedule 02.02.2019
comment
Потому что, если это происходит только на определенных устройствах и отлично работает на стандартном Android, вам может потребоваться выполнить отладку на этом конкретном устройстве. Посмотрите, есть ли рядом с вами лаборатория устройств.   -  person Michael Dodd    schedule 02.02.2019


Ответы (1)


Я не думаю, что это будет xiaomi проблемой. это скорее результат неудачной миграции, когда новый столбец не был добавлен, и впоследствии пользователь может по-прежнему работать с предыдущей версией таблицы. и нет другого логического объяснения отсутствующему столбцу) просто потому, что оператор CREATE TABLE либо работает, либо нет.

все еще можно обойти это с помощью ALTER TABLE. например. когда это SQLiteException происходит, addColumnIfNotExists("dialogues", "topChat", "INTEGER DEFAULT 0"); ... чтобы не вызвать потерю данных из-за удаления таблицы только потому, что в ней отсутствует какой-либо столбец.

public void addColumnIfNotExists(String tableName, String columnName, String dataType) {
    Cursor cursor = null;
    try {
        cursor = db.rawQuery("SELECT * FROM " + tableName, null);
        if(! Arrays.asList(cursor.getColumnNames()).contains(columnName)) {
            db.execSQL(String.format("ALTER TABLE %s ADD COLUMN %s %s", tableName, columnName, dataType));
        }
    } finally {
        if(cursor != null) {
            cursor.close();
        }
    }
}
person Martin Zeitler    schedule 02.02.2019
comment
Я написал, что это не проблема миграции. Моя база данных обновляется правильно, когда это необходимо, и эта таблица и столбец не менялись в течение длительного времени до этой ошибки. - person lxknvlk; 02.02.2019
comment
@lxknvlk по-прежнему звучит маловероятно, что CREATE TABLE преуспел бы так же, и в запросе нет ничего особенного, где версия драйвера будет иметь значение, за исключением того, что он не предоставляет значение DEFAULT для этого столбца ... предоставленный метод должен решить проблему, независимо от причины. - person Martin Zeitler; 02.02.2019