Android cursor.getColumnNames()不包含新添加的列

问题描述 投票:1回答:1

我使用下面的代码来测试列是否存在:

  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 * FROMselect * from改为isColumnExists,那么一切都变得正常了。

enter image description here enter image description here

android sql sqlite
1个回答
1
投票

我相信原因是SQLite(我强烈怀疑Cursor,因此更正确的SDK的Android SQLite方面)是缓存数据(可能因为从不从数据库中检索底层数据,因为不需要获取数据(就光标而言))。

我已经尝试了各种检查,包括放入断点,检查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;
    */
}
  • 请注意您的代码已保留但已注释掉。

我相信评估强制刷新缓存(即我尝试了它,它确实动态地改变以包括列)。

© www.soinside.com 2019 - 2024. All rights reserved.