升级时更改sqlite3数据库数据

时间:2017-10-27 13:45:56

标签: android

我正在编写Android应用程序并扩展SqliteOpenHelper类以访问,创建和升级数据库。在旧版本的应用程序中,我们将域名保存到数据库中。在将来的版本中,我们希望进行更改,以便保存完全限定的URL而不是域名。 (例如,用于保存“示例”现在想要保存“www.example.com”)。一个要求是我们不会在升级期间删除任何表,因此删除保存此值的表,然后在升级后不能将新值写为完全限定的URL。

我知道如何在数据库升级时更改表等,但我想知道是否有一种方法可以在升级过程中升级数据库中的数据值(如果可以有条件地完成,则更好)。

我搜索了Sqlite文档但找不到我要找的内容。

我的一个想法是在SqliteOpenHelper的onUpgrade()方法中进行查询。如下所示:

    @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    for (int i = oldVersion; i < newVersion; i++) {
        if (oldVersion == VERSION_SAVING_DATA_AS_DOMAIN) {
            //Query database for domain
            //Convert domain to fully qualified url
            //Write fully qualified url to database
            //Do database upgrade
        }
    }
}

不确定上面显示的策略是不是很糟糕,也不确定是否有一种更明显的方法可以解决这个问题。我不会考虑这个问题。

3 个答案:

答案 0 :(得分:1)

这与升级架构的工作方式完全相同。您只运行SQL语句。只需使用Update语句而不是Alter Table

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  if (oldVersion<2) {
    // do upgrade from 1 to 2
  }

  if (oldVersion<3) {
    // do upgrade from 2 to 3, which will also cover 1->3,
    // since you just upgraded 1->2
  }

  // and so on
}

您可以使用SwitchIf语句来检查旧版本。我个人更喜欢If,因为我认为它更具可读性,而且更容易下降。

参考: Confusion: How does SQLiteOpenHelper onUpgrade() behave? And together with import of an old database backup?

答案 1 :(得分:1)

我不知道你为什么要使用for循环。您可以升级数据库,如下例所示:

// Database Version
private static final int DATABASE_VERSION = 5;
// Database Name
private static final String DATABASE_NAME = "exampleDB";


private DataBaseHandler(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    this.context = context;
}
[..]

@Override
public void onUpgrade(final SQLiteDatabase db, int oldVersion, int newVersion) {
    if(oldVersion < 3) {
        //code for upgrading to database version 3 and higher
        [..]
    }
    if(oldversion < 5){
        //code for upgrading to database version 5 and higher
        upgradeToFullyQualifiedUrls(db);
    }
}

如果您当前的版本是例如4并且您想要更改数据库中的URL,则将DATABASE_VERSION设置为5并添加SQL UPDATE查询以更改if(oldversion < 5)之后的URL。数据库版本低于5的应用的所有版本都将获得新的网址,版本将在onUpgrade之后自动更改为5。

答案 2 :(得分:0)

上面的答案让我找到了我在这里发布的确切问题的解决方案。

问题是我在以前的数据库版本中向数据库写了一个任意子域名,并希望能够将数据库中的每个任意子域名转换为以下形式的字符串:&#34; { {3}}&#34; 其他复杂情况是,在之前的数据库升级中,我开始编写&#34; https://arbitrarysubdomain.example.com&#34;而不是&#34; arbitrarysubdomain&#34;就像我在最古老的数据库版本中一样。最后,现有值可能为null或空字符串,在这种情况下,我想将值转换为null。

这是解决我的问题并满足约束条件的sqlite语句:

UPDATE preferences
    SET subdomain = CASE WHEN ((SELECT subdomain FROM preferences WHERE subdomain LIKE '%.com') IS NOT NULL) THEN
                             (SELECT subdomain FROM preferences WHERE subdomain LIKE '%.com')
                         WHEN ((SELECT subdomain FROM preferences) IS NOT NULL AND (SELECT subdomain FROM preferences) IS NOT '') THEN
                             'https://' || (SELECT subdomain FROM preferences) || '.example.com'
                         ELSE
                             NULL
                    END;

所以现在当运行onUpgrade并且​​我从上一个受影响的版本升级到我添加修复的新版本时,我执行此语句。

我想在此之后写的另一个声明会将我的偏好表的子域列重命名为更具描述性的其他内容。