我使用下面的代码测试一列是否存在:
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
,则一切正常。
答案 0 :(得分: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;
*/
}
我认为评估会强制刷新缓存(即,是的,我尝试过,但确实会动态更改以包括该列)。