【问题标题】:SQLite data migration from Version 0 to 1SQLite 数据从版本 0 迁移到 1
【发布时间】:2017-09-20 07:44:31
【问题描述】:

之前我使用db = openOrCreateDatabase("LOCALTILEDB", Context.MODE_PRIVATE, null); 创建了一个数据库,它正在创建一个版本为“0”的数据库。

在下一个版本的应用程序中,我正在使用 SQLiteOpenHelper 类,其中 OnUpgrade 方法显示调用的错误,数据库版本不能为 '0'。

所以请任何人帮助我将数据从我的 0 版本数据库迁移到版本 1 数据库。

【问题讨论】:

  • 我还没有完全研究这个,但是你可以做的是打开你当前的数据库(使用 getWriteableDatabase())然后运行,使用 execSQL 方法,以下SQLPRAGMA user_version = 1。但是,接下来是如何处理更改版本号。我可能会玩一点游戏,看看我能想出什么。
  • 根据答案,您不需要使用 PRAGMA 来更改版本。

标签: android android-sqlite sqliteopenhelper


【解决方案1】:

在使用 SQLiteOpenHelper 扩展的类中,将 super(context, DATABASE_NAME, null, DATABASE_VERSION) 传递给默认构造函数。例如。

public class MyDBHelper extends SQLiteOpenHelper {

// Database Version
private static final int DATABASE_VERSION = 1;

// Database Name
private static final String DATABASE_NAME = "MyDb";


public MyDBHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase aSqLiteDatabase) {

}  @Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

} 

}

【讨论】:

    【解决方案2】:

    我怀疑您所做的是编写通过 super 传递的 0 版本,例如:-

    public static final int DBVERSION = 0;
    
    public SO46316125DBHlpr(Context context) {
        super(context, DBNAME, null, DBVERSION);
    }
    

    这将导致包含Version must be >= 1, was 0的异常

    例如:-

    09-20 21:16:40.631 1840-1840/mjt.soqanda E/AndroidRuntime: FATAL EXCEPTION: main
                                                               Process: mjt.soqanda, PID: 1840
                                                               java.lang.RuntimeException: Unable to start activity ComponentInfo{mjt.soqanda/mjt.soqanda.MainActivity}: java.lang.IllegalArgumentException: Version must be >= 1, was 0
                                                                   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
                                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
                                                                   at android.app.ActivityThread.access$800(ActivityThread.java:151)
                                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
                                                                   at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                   at android.os.Looper.loop(Looper.java:135)
                                                                   at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                                   at java.lang.reflect.Method.invoke(Method.java:372)
                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
                                                                Caused by: java.lang.IllegalArgumentException: Version must be >= 1, was 0
                                                                   at android.database.sqlite.SQLiteOpenHelper.<init>(SQLiteOpenHelper.java:99)
                                                                   at android.database.sqlite.SQLiteOpenHelper.<init>(SQLiteOpenHelper.java:77)
                                                                   at mjt.soqanda.SO46316125DBHlpr.<init>(SO46316125DBHlpr.java:23)
    

    但是,简单地编写一个非零的正版本,将其传递给 super 方法,然后将导致使用该版本。


    例如我已将数据库设置为版本 0(使用 PRAGMA user_version=0,然后是 PRAGMA user_version(检索版本)并具有:-

    09-20 21:29:35.117 19172-19172/? D/DBVERSION: The Database User Version is 1
    09-20 21:29:35.118 19172-19172/? D/CHGDBVERSION: Attempting to alter DB Version from 1 to new version 0
    09-20 21:29:35.152 19172-19172/? D/CHGDBVERSION: DB Version changed successfully, DB Version is now 0
    

    然后我使用版本 100:-

    public static final int DBVERSION = 100;
    
    public SO46316125DBHlpr(Context context) {
        super(context, DBNAME, null, DBVERSION);
    }
    

    所以这会直接跳转到版本 100(onUpgrade 方法为空):-

    09-20 21:35:45.344 27937-27937/mjt.soqanda D/DBVERSION: The Database User Version is 100
    

    当然 1 也可以。


    为了测试/生产上述内容,我使用了以下方法:-

    public void showDBVersion() {
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor csr = db.rawQuery("PRAGMA user_version",null);
        if (csr.moveToFirst()) {
            Log.d("DBVERSION","The Database User Version is " + csr.getString(0));
        }
    }
    
    
    public int alterDBVersion(SQLiteDatabase db, int fromversion, int toversion) {
    
        int current_version = -1;
        int changed_version = -1;
    
        Cursor csr = db.rawQuery("PRAGMA user_version;",null);
        if (csr.moveToFirst()) {
            current_version = csr.getInt(0);
        } else {
            Log.d("CHGDBVERSION","Unable to get the current version.");
            return current_version;
        }
    
        if (current_version == fromversion) {
            Log.d("CHGDBVERSION","Attempting to alter DB Version from " +
                    Integer.toString(fromversion) +
                    " to new version " +
                    Integer.toString(toversion)
            );
            db.rawQuery("PRAGMA user_version=" + Integer.toString(toversion) + ";",null); //NOTE 1
            db.execSQL("PRAGMA user_version=" + Integer.toString(toversion) + ";");
        }
    
        csr = db.rawQuery("PRAGMA user_version;",null);
        if (csr.moveToFirst()) {
            changed_version = csr.getInt(0);
        } else {
            Log.d("CHGDBVERSION","Unable to get the new/changed version.");
            return -2;
        }
        if (current_version != fromversion || changed_version != toversion) {
            Log.d("CHGDBVERSION",
                    "DB Version was not changed as requested. Version is now " +
                            Integer.toString(changed_version));
            return -3;
        } else {
            Log.d("CHGDBVERSION","DB Version changed successfully, DB Version is now " +
            Integer.toString(changed_version));
        }
        return 0;
    }
    

    注意 1 不起作用必须按照Android: PRAGMA statements that set data don't work 使用 execSQL

    在MainActivity中使用以下代码

        SO46316125DBHlpr dbhlpr = new SO46316125DBHlpr(this);
        dbhlpr.showDBVersion();
        dbhlpr.alterDBVersion(dbhlpr.getWritableDatabase(),1,0);
    

    明显改变参数(第一个是要更改的版本,因此当前版本必须匹配它,第二个是要更改到的版本,如果第一个匹配)。以上示例将版本 1 更改为版本 0。

    【讨论】:

      猜你喜欢
      • 2018-04-27
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-13
      相关资源
      最近更新 更多