原因:android.database.sqlite.SQLite异常:无法从版本升级只读数据库



看不懂这个。我正在升级数据库,我已经创建了一个函数,通过将原表重命名为临时表,然后创建一个新表,重新命名的字段,然后将所有数据从临时表复制到新表,但它在复制数据的部分失败。

执行重命名的函数:

public void modifyColumn(SQLiteDatabase db, String oldColumnName, String newColumnName, String[] newColumnConstraints) {
    // get current table columns
    String sql = String.format("PRAGMA table_info('%s')", TABLE_NAME);
    Cursor cursor = db.rawQuery(sql, new String[] {});
    int length = cursor.getCount();
    String[] oC = new String[length], nC = new String[length], c = new String[length];
    while(cursor.moveToNext()){
        int cid = cursor.getInt(cursor.getColumnIndex("cid"));
        String name = cursor.getString(cursor.getColumnIndex("name"));
        String type = cursor.getString(cursor.getColumnIndex("type"));
        int notnull = cursor.getInt(cursor.getColumnIndex("notnull"));
        String dflt = cursor.getString(cursor.getColumnIndex("dflt_value"));
        int pk = cursor.getInt(cursor.getColumnIndex("pk"));
        Vector<String> constraints = new Vector<String>();
        // add data type to field
        constraints.add(type);
        // add primary key option to field
        if(pk > 0)
            constraints.add("PRIMARY KEY");
        // add not null option to field
        if(notnull > 0)
            constraints.add("NOT NULL");
        // add default value to field
        if(dflt != null)
            constraints.add("DEFAULT " + dflt);
        String cName = name;
        String cType = TextUtils.join(" ", constraints.toArray());
        oC[cid] = cName;
        cName = (cName.equals(oldColumnName))? newColumnName : cName;
        nC[cid] = cName;
        if(newColumnConstraints != null)
            cType = TextUtils.join(" ", newColumnConstraints);
        c[cid] = cName + " " + cType;
    }

    // rename old table
    this.renameTable(db, "tmp_" + TABLE_NAME);
    // create new table with modified column
    this.createTable(db, TABLE_NAME, c);
    // copy data from temporary table to new table
    sql = "INSERT INTO " + TABLE_NAME + " (" + TextUtils.join(", ", nC) + 
            ") SELECT (" + TextUtils.join(", ", oC) + ") FROM tmp_" + TABLE_NAME;
    db.execSQL(sql);
    // drop temporary table
    db.execSQL("DROP TABLE tmp_" + TABLE_NAME);
}

在"将数据从临时表复制到新表"注释处,执行前的sql看起来像:

INSERT INTO vehicles (_id, vLabel, vYear, vMake, vModel, vOption, vDetail, vAdded) SELECT (id, vLabel, vYear, vMake, vModel, vOption, vDetail, vAdded) FROM tmp_vehicles

然后我得到以下错误输出:

06-08 19:33:05.888: E/Database(21562): Failure 1 (near ",": syntax error) on 0x2037d8 when preparing 'INSERT INTO vehicles (_id, vLabel, vYear, vMake, vModel, vOption, vDetail, vAdded) SELECT (id, vLabel, vYear, vMake, vModel, vOption, vDetail, vAdded) FROM tmp_vehicles'.
06-08 19:33:08.711: W/dalvikvm(21562): threadid=1: thread exiting with uncaught exception (group=0x4001f560)
06-08 19:33:08.771: E/AndroidRuntime(21562): FATAL EXCEPTION: main
06-08 19:33:08.771: E/AndroidRuntime(21562): java.lang.RuntimeException: Unable to start activity 
06-08 19:33:08.771: E/AndroidRuntime(21562):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1648)
06-08 19:33:08.771: E/AndroidRuntime(21562):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1662)
06-08 19:33:08.771: E/AndroidRuntime(21562):    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
06-08 19:33:08.771: E/AndroidRuntime(21562):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
06-08 19:33:08.771: E/AndroidRuntime(21562):    at android.os.Handler.dispatchMessage(Handler.java:99)
06-08 19:33:08.771: E/AndroidRuntime(21562):    at android.os.Looper.loop(Looper.java:130)
06-08 19:33:08.771: E/AndroidRuntime(21562):    at android.app.ActivityThread.main(ActivityThread.java:3696)
06-08 19:33:08.771: E/AndroidRuntime(21562):    at java.lang.reflect.Method.invokeNative(Native Method)
06-08 19:33:08.771: E/AndroidRuntime(21562):    at java.lang.reflect.Method.invoke(Method.java:507)
06-08 19:33:08.771: E/AndroidRuntime(21562):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
06-08 19:33:08.771: E/AndroidRuntime(21562):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624)
06-08 19:33:08.771: E/AndroidRuntime(21562):    at dalvik.system.NativeStart.main(Native Method)

选择语法错误。

代替

SELECT (column1, column2, ...)

SELECT column1, column2, ...

。去掉括号

最新更新