简体   繁体   English

Android SQLiteDatabase更新架构,不会丢失数据

[英]Android SQLiteDatabase update schema without loosing data

I'm using SQLiteDatabase in my app. 我在我的应用程序中使用SQLiteDatabase。 My SQLiteOpenHelper.onUpgrade(..) method looks like this: 我的SQLiteOpenHelper.onUpgrade(..)方法如下所示:

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    //Save current data
    ArrayList<Course> tempCourses = getAllCourses();

    //Drop tables
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_COURSES);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_ASSIGNMENTS);

    //create new tables
    onCreate(db);

    //Add temp data back to the database
    for (Course course : tempCourses) {
        addCourse(course);
    }
}

I want to keep the old userdata when upgrading the database schema. 升级数据库架构时,我想保留旧的用户数据。 However I get the following error when i increase the database version and start my app: 但是,当我增加数据库版本并启动我的应用程序时,出现以下错误:

...
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tak3r07.unihelper/com.tak3r07.CourseStatistics.MainActivity}: java.lang.IllegalStateException: getDatabase called recursively
...

This is because getAllCourses() will open the database again to get the data which calls the onUpgrade method (obvious loop). 这是因为getAllCourses()将再次打开数据库以获取调用onUpgrade方法的数据(显而易见的循环)。 But how should i store my userdata then? 但是我该如何存储用户数据呢?

Regards, Tak3r07 问候,Tak3r07

The ALTER TABLE command can be used to perform some schema changes on existing tables without losing data. ALTER TABLE命令可用于对现有表执行一些架构更改,而不会丢失数据。 If you do find that you need to create the table from scratch, you should follow the following pattern: 如果确实发现需要从头开始创建表,则应遵循以下模式:

  1. Begin transaction 开始交易
  2. Create the new table 创建新表
  3. Do a insert .. select statement 做一个插入..选择语句
  4. Drop the old tables 放下旧桌子
  5. Commit transaction 提交交易

If any of the steps fail, you still have the data, and you can pick up at any step to finish the upgrade if it fails for any reason. 如果任何步骤失败,那么您仍然有数据,并且如果由于任何原因失败,您可以在任何步骤进行升级。 You do not want to load all the courses into your app's memory like you're doing and then drop the tables because if your app fails to insert the courses back into the db, you'll lose all your data. 希望像现在那样将所有课程加载到应用程序的内存中,然后删除表,因为如果您的应用程序无法将课程重新插入数据库,则会丢失所有数据。 Do it all in SQL. 用SQL完成所有操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM