【发布时间】:2011-04-21 10:48:19
【问题描述】:
我在读取 Android SQLite 数据库中的列的两种方法之间得到不一致的结果。
首先,根据此处接受的答案,这是数据库升级例程的一部分:Upgrade SQLite database from one version to another?
该技术涉及使用临时名称将当前表移走,使用新架构创建一个新表,然后在删除旧临时表之前将相关数据从旧表复制到新表中。
我遇到的特殊问题是当我从架构中删除一列时。因此,旧版本的表中存在特定列,但新版本中不存在。
该答案建议使用这样的方法来列出表中的列:
/**
* Returns a list of the table's column names.
*/
private List<String> getColumns(SQLiteDatabase db, final String tableName) {
List<String> ar = null;
Cursor c = null;
try {
c = db.rawQuery("SELECT * FROM " + tableName + " LIMIT 1", null);
if (c != null) {
ar = new ArrayList<String>(Arrays.asList(c.getColumnNames()));
}
} finally {
if (c != null)
c.close();
}
return ar;
}
在我用一个临时名称将它移走并替换它之前,这在旧表上工作得很好。当我稍后再次运行相同的查询时,在新创建的空表上,它仍然列出了旧表模式以及不再存在的列名。它看起来好像在为该查询重用过时的缓存结果。
如果我以不同的方式读取列,而是使用它,那么它会按预期返回新的列列表:
private void listColumns(SQLiteDatabase db, final String tableName) {
final String query = "PRAGMA table_info(" + tableName + ");";
Cursor c = db.rawQuery(query, null);
while (c.moveToNext()) {
Log.v("MyApp", "Column: " + c.getString(1));
}
c.close();
}
完整的序列是:
final String tempTableName = "temp_" + tableName;
table.addToDb(db); // ensure it exists to start with
// get column names of existing table
final List<String> columns = getColumns(db, tableName);
// backup table
db.execSQL("ALTER TABLE " + tableName + " RENAME TO " + tempTableName);
// create new table
table.addToDb(db);
// delete old columns which aren't in the new schema
columns.retainAll(getColumns(db, tableName));
// restore data from old into new table
String columnList = TextUtils.join(",", columns);
db.execSQL(String.format("INSERT INTO %s (%s) SELECT %s from %s", tableName, columnList, columnList,
tempTableName));
// remove backup
db.execSQL(DROP_TABLE + tempTableName);
结果不同的原因是什么?
【问题讨论】:
-
移动桌子的代码是什么?
-
Rajath:将其添加到问题中。
-
我也有同样的问题! stackoverflow.com/questions/54851066/…