【问题标题】:Android database strangeness listing columnsAndroid 数据库异常列表列
【发布时间】: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);

结果不同的原因是什么?

【问题讨论】:

标签: android database sqlite


【解决方案1】:

我假设你做过类似的事情:

ALTER TABLE "main"."mytable" RENAME TO "newtable"; 
CREATE TABLE "main"."mytable" ("key1" text PRIMARY KEY,"key2" text,"key3" text);
INSERT INTO "main"."mytable" SELECT "key1","key2","key3" FROM "main"."newtable"; 
DROP TABLE "main"."newtable";

如果你有,请分享等效代码,以排除这部分的任何错误。

【讨论】:

    【解决方案2】:

    我从来没有深究过这个。我只是最终使用了我提到的第二种方法,它没有出现问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-01
      • 2013-09-25
      相关资源
      最近更新 更多