Android cursor.getColumnNames () не содержит новый добавленный столбец - PullRequest
0 голосов
/ 10 сентября 2018

Я использую код ниже, чтобы проверить, существует ли столбец:

  public static boolean isColumnExists(String tableName, String columnName) {
    Cursor cursor = null;
    try {
        SQLiteDatabase db = getDatabase();
        cursor = db.rawQuery("SELECT * FROM " + tableName + " LIMIT 0", null);
        String[] cloNames = cursor.getColumnNames();
        if (cloNames != null) {
            for (String temp : cloNames) {
                if (columnName.equalsIgnoreCase(temp)) {
                    return true;
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (null != cursor && !cursor.isClosed()) {
            cursor.close();
        }
    }

    return false;
}

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

    if (!isColumnExists("PositionCache", "hello2")) {
        // First try will insert column to database
        getDatabase().execSQL("alter table PositionCache add hello2 Integer default 0");
    }
    if (!isColumnExists("PositionCache", "hello2")) {
        // Second try will give and error about duplicate column of hello2
        getDatabase().execSQL("alter table PositionCache add hello2 Integer default 0");
    }

Мне нужно знать причину такого ненормального явления.


Если я изменю SELECT * FROM на select * from в методе isColumnExists, тогда все станет нормально.

enter image description here enter image description here

1 Ответ

0 голосов
/ 10 сентября 2018

Я полагаю, что причина в том, что SQLite (я сильно подозреваю, что Курсор, так что более корректно в аспекте Android SQLite SDK) кеширует данные (возможно, потому что базовые данные никогда не извлекаются из базы данных, так как нет необходимости получать данные (что касается курсора)).

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

Как только я добавляю альтернативную проверку, используя PRAGMA table_info(*table_name*);, столбец существует.

Поэтому я бы предложил использовать следующее: -

public static boolean isColumnExistsOld(String tableName, String columnName) {

    Cursor csr = getDatabase().rawQuery("PRAGMA table_info(" + tableName + ")",null);
    while(csr.moveToNext()) {
        if (csr.getString(csr.getColumnIndex("name")).equalsIgnoreCase(columnName)) {
            return true;
        }
    }
    return false;
    /*
    Cursor cursor = null;
    try {
        SQLiteDatabase db = getDatabase();
        cursor = db.rawQuery("SELECT * FROM " + tableName + " LIMIT 1", null);
        cursor.moveToFirst();
        String[] cloNames = cursor.getColumnNames();
        if (cloNames != null) {
            for (String temp : cloNames) {
                if (columnName.equalsIgnoreCase(temp)) {
                    return true;
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (null != cursor && !cursor.isClosed()) {
            cursor.close();
        }
    }
    boolean rv = colfound;
    return false;
    */
}
  • Обратите внимание, что ваш код оставлен, но закомментирован.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...