Android:升级数据库版本并添加新表

Jay*_*ayu 114 database sqlite android

我已经为我的应用程序创建了sqlite表,但现在我想在数据库中添加一个新表.

我更改了DB版本如下

private static final int DATABASE_VERSION = 2;
Run Code Online (Sandbox Code Playgroud)

并添加字符串以创建表

private static final String DATABASE_CREATE_color = 
   "CREATE TABLE IF NOT EXISTS files(color text, incident_id text)";
Run Code Online (Sandbox Code Playgroud)

onCreate并且onUpgrade,如下:

@Override
    public void onCreate(SQLiteDatabase database) {
        database.execSQL(DATABASE_CREATE_incident);
        database.execSQL(DATABASE_CREATE_audio);
        database.execSQL(DATABASE_CREATE_video);
        database.execSQL(DATABASE_CREATE_image);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //drop table and add new tables when version 2 released.
        db.execSQL(DATABASE_CREATE_color);

    }
Run Code Online (Sandbox Code Playgroud)

但由于某种原因,没有创建新表.我究竟做错了什么?

jks*_*der 273

1.关于onCreate()和onUpgrade()

onCreate(..)每当应用程序刚刚安装时调用. onUpgrade每当升级和启动应用程序并且数据库版本不同时调用.

2.增加db版本

你需要一个像这样的构造函数:

MyOpenHelper(Context context) {
   super(context, "dbname", null, 2); // 2 is the database version
}
Run Code Online (Sandbox Code Playgroud)

重要提示:单独增加应用程序版本是不够的onUpgrade!

3.不要忘记你的新用户!

别忘了添加

database.execSQL(DATABASE_CREATE_color);
Run Code Online (Sandbox Code Playgroud)

您的onCreate()方法或新安装的应用程序将缺少该表.

4.如何处理多个数据库随时间的变化

如果您有连续的应用程序升级,其中有几个已进行数据库升级,您需要确保检查oldVersion:

onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
   switch(oldVersion) {
   case 1:
       db.execSQL(DATABASE_CREATE_color);
       // we want both updates, so no break statement here...
   case 2:
       db.execSQL(DATABASE_CREATE_someothertable); 
   }
}
Run Code Online (Sandbox Code Playgroud)

这样,当用户从版本1升级到版本3时,他们将获得两个更新.当用户从版本2升级到3时,他们只会获得版本3更新...毕竟,每次发布更新时,都不能指望100%的用户群升级.有时他们会跳过更新或12 :)

5.在开发过程中保持您的版本号控制

最后......打电话

adb uninstall <yourpackagename>
Run Code Online (Sandbox Code Playgroud)

完全卸载应用程序.当你再次安装时,你可以保证在开发时onCreate不必将数据库版本增加到平流层......

  • 关于添加对`onCreate()`的调用的好处 (7认同)
  • 关于#4:使用传递的`oldVersion`参数不是更好的主意吗?如果任何升级语句是可重复的,您最终可能会在最新的数据库上重复它们.如果其中一个语句是截断表,那将是非常糟糕的. (5认同)
  • @Greyson:好点!老实说,我觉得从来没有真正考虑它有点愚蠢.有时我认为我们习惯使用我们想要的论点而忽略其余的论点! (3认同)
  • `newVersion`有点无用,因为你总是在构造函数中设置当前的数据库版本(参见第2部分),它总是匹配.这里的关键思想是,您不希望只是从用户直接升级到"newVersion"而不通过其间的所有其他增量升级. (3认同)
  • @kai`CREATE_READINGS`逻辑永远不应该在onUpgrade中,因为它是在你的第一个版本的`onCreate`方法中.将`onUpgrade`开关中的案例视为"我正在升级`oldVersion`".如果从版本1升级,则不会创建读数表,因为它应该已经存在.希望这是有道理的...... (2认同)

Gre*_*son 9

您的代码看起来正确.我的建议是数据库已经认为它已经升级了.如果在增加版本号后执行项目,但在添加execSQL调用之前,测试设备/模拟器上的数据库可能已经相信它在版本2中.

验证这一点的一种快速方法是将版本号更改为3 - 如果之后升级,您知道这只是因为您的设备认为它已经升级.