SQLite升级时为新列重复列名

时间:2017-04-11 21:52:57

标签: android sqlite android-sqlite

在更新应用程序时,用户升级到新版本的本地SQLite数据库时,我遇到了不一致,不可重现的崩溃。

Fatal Exception: android.database.sqlite.SQLiteException: duplicate column name: upload_pending (code 1): , while compiling: ALTER TABLE purchases ADD COLUMN upload_pending TINYINT DEFAULT 0
#################################################################
Error Code : 1 (SQLITE_ERROR)
Caused By : SQL(query) error or missing database.
    (duplicate column name: upload_pending (code 1): , while compiling: ALTER TABLE purchases ADD COLUMN upload_pending TINYINT DEFAULT 0)
#################################################################

这个版本的应用程序是新版本,它告诉我最可能的错误是SQLiteOpenHelper的onUpgrade方法被调用两次。以下是处理升级的逻辑:

@Override   
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    for(int currentUpgrade = oldVersion + 1; currentUpgrade <= newVersion; currentUpgrade++) {
        switch(currentUpgrade) {
            case 2: 
                //upgrade to db v2
                break;
            case 3:
                //upgrade to db v3
                break;
            //etc
            case 7:
                methodWhichUpdatesAnotherTable(db);
                db.execSQL("ALTER TABLE " + Purchases.TABLE_NAME
                            + " ADD COLUMN " + Purchases.UPLOAD_PENDING + " TINYINT DEFAULT 0");
                break;
        }
    }
}

编辑:我已更新代码以包含重要内容。失败的行不是升级中的第一个ALTER语句。首先,调用一个方法,它生成两个不同的alter语句(在不同的表上),这部分工作正常。这似乎消除了它是并发问题的可能性,因为如果是这样的话,这将是第一个失败的。

看看这个,我能看到这种情况发生的唯一方法就是Android是两次调用升级,而不调整oldVersionnewVersion参数,导致案例7被调用两次。相反,可能是调用onCreate的情况,之后调用onUpgrade,同样提供给该方法的数据库版本不正确。

正如我在开始时所提到的,我无法重现此错误,并且只发生在<1%的用户身上,但对我来说,想要解决它是显而易见的。如果有人猜测我会很感激,如果您需要更多信息,请随时提出。谢谢!

1 个答案:

答案 0 :(得分:2)

有同样的问题。原来,我在4之前为oldVersions创建了表,并为10之前的版本添加了列。因此,对于oldVersions pre 4执行了两个语句CREATE TABLE和ALTER TABLE ADD COLUM:

if ( oldVersion < 4 && newVersion >= 4 ) { 
    TestTableDao.createTable( db, true );
}

if ( oldVersion < 10 && newVersion >= 10 ) { 
   db.execSQL( "ALTER TABLE TEXT_TABLE ADD COLUMN NEW_COLUMN TEXT" );
}

修复是在创建表后检查oldVersion:

 if ( oldVersion < 10 && newVersion >= 10 ) { 
   if( oldVersion >=4 )
       db.execSQL( "ALTER TABLE TEXT_TABLE ADD COLUMN NEW_COLUMN TEXT" );
}

希望对某人有所帮助。