将SQLite数据库从一个版本升级到另一个版本?

Moh*_*nde 14 java sqlite android upgrade

我收到一个错误,Logcat说某个列(在我的SQLiteOpenHelper子类中)不存在.我以为我可以通过更改DATABASE_CREATE字符串来升级数据库.但显然不是,那么我如何(逐步)将我的SQLite数据库从版本1升级到版本2?

如果问题看起来像"noobish",我很抱歉,但我仍然在学习Android.

@ Pentium10这是我在onUpgrade中所做的:

private static final int DATABASE_VERSION = 1;

....

switch (upgradeVersion) {
case 1:
    db.execSQL("ALTER TABLE task ADD body TEXT");
    upgradeVersion = 2;
    break;
}

...
Run Code Online (Sandbox Code Playgroud)

Pen*_*m10 47

好的,在你遇到更大的问题之前你应该知道SQLite在ALTER TABLE命令上是有限的,它允许add并且rename只允许删除/删除,这是通过重新创建表来完成的.

您应始终拥有新的表创建查询,并将其用于升级和传输任何现有数据.注意:onUpgrade方法为您的sqlite帮助程序对象运行一个,您需要处理其中的所有表.

那么推荐使用什么升级:

  • 的BeginTransaction
  • 运行一个表创建if not exists(我们正在进行升级,因此该表可能还不存在,它将失败更改和删除)
  • 列出现有列的列表 List<String> columns = DBUtils.GetColumns(db, TableName);
  • 备份表(ALTER table " + TableName + " RENAME TO 'temp_" + TableName)
  • 创建新表(最新的表创建模式)
  • 获取与新列的交集,这次是从升级后的表中获取的列(columns.retainAll(DBUtils.GetColumns(db, TableName));)
  • 恢复数据(String cols = StringUtils.join(columns, ","); db.execSQL(String.format( "INSERT INTO %s (%s) SELECT %s from temp_%s", TableName, cols, cols, TableName)); )
  • 删除备份表(DROP table 'temp_" + TableName)
  • setTransactionSuccessful

.

public static List<String> GetColumns(SQLiteDatabase db, 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()));
        }
    } catch (Exception e) {
        Log.v(tableName, e.getMessage(), e);
        e.printStackTrace();
    } finally {
        if (c != null)
            c.close();
    }
    return ar;
}

public static String join(List<String> list, String delim) {
    StringBuilder buf = new StringBuilder();
    int num = list.size();
    for (int i = 0; i < num; i++) {
        if (i != 0)
            buf.append(delim);
        buf.append((String) list.get(i));
    }
    return buf.toString();
}
Run Code Online (Sandbox Code Playgroud)

  • 我不使用这些版本.你不需要.您始终升级到最新版本,您无需升级所有版本.拿这个:你有v1,v10,v50,v80.您当前定义的版本是v100.即使从v1或v50升级,也需要具有v100的表模式.所以我只创建**最新的**(这意味着v100)表模式,我不打扰我升级的版本.我不需要知道它是v1还是v50,它的版本是独立的.您始终升级到最新版本,您无需知道从哪个版本. (3认同)