1

我正在尝试将三个新表添加到我现有的 sqlite 数据库中,并且我遇到了数据库版本在成功升级后没有更新的问题。下面是运行的 DatabaseHelper:

private static class DatabaseHelper extends SQLiteOpenHelper {

    public DatabaseHelper(Context context, String name, CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        Log.w(TAG, "Current db version is " + db.getVersion());
        db.execSQL(ORIGINAL_DATABASE_CREATE);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(TAG, "Old Version " + oldVersion + " New Version " + newVersion + " db.getVersion is " + db.getVersion());
        db.execSQL(NEW_TABLE_1_DATABASE_CREATE);
        db.execSQL(NEW_TABLE_2_DATABASE_CREATE);
        db.execSQL(NEW_TABLE_3_DATABASE_CREATE);
        db.setVersion(newVersion);
        Log.w(TAG, "Version after onUpgrade is " + db.getVersion());
    }       
}

下面是我的 open() 函数:

public VehicleExpDbAdapter open() throws SQLException {
    mDbHelper = new DatabaseHelper(mCtx, DATABASE_NAME, null, DATABASE_VERSION);
    mDb = mDbHelper.getWritableDatabase();
    return this;
}

下面是我的 close() 函数:

public void close() {
    mDb.close();
    mDbHelper.close();
}

所以在第一次运行时使用更高的 DATABASE_VERSION 会发生第一个 onUpgrade 日志读取:旧版本 1 新版本 2 db.getVersion 是 1

第二个Log是:onUpgrade后的Version is 2

但是,当在 onUpgrade 运行后再次访问数据库时,数据库的版本号没有更新,它通过 onUpgrade 运行,onUpgrade 中的第一个日志读取:旧版本 1 新版本 2 db.getVersion 为 1

然后应用程序崩溃了,因为它试图创建一个已经存在的表。

我也尝试过不在 onUpgrade 中手动设置数据库版本。这也不起作用。我还尝试通过运行来更新版本号...

db.execSQL("PRAGMA user_version = " + newVersion);

...在 onUpgrade 结束时。

编辑:

根据 Aswin Kumar 的建议,我已将 onUpgrade 更改为备份现有表并删除所有表,然后重新创建它们。这还没有解决我的版本问题。下面是我的 onUpgrade 和 onCreate:

@Override
    public void onCreate(SQLiteDatabase db) {
        Log.w(TAG, "Current db version is " + db.getVersion());

        db.execSQL(ORIGINAL_DATABASE_CREATE);

        db.execSQL(NEW_TABLE_1_DATABASE_CREATE);
        db.execSQL(NEW_TABLE_2_DATABASE_CREATE);
        db.execSQL(NEW_TABLE_3_DATABASE_CREATE);

    }

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

        Log.w(TAG, "Old Version " + oldVersion + " New Version " + newVersion + " db.getVersion is " + db.getVersion());

        mOldDbContents = backupTables(db);

        db.execSQL("DROP TABLE IF EXISTS " + ORIGINAL_DATABASE_CREATE);
        db.execSQL("DROP TABLE IF EXISTS " + NEW_TABLE_1_DATABASE_CREATE);
        db.execSQL("DROP TABLE IF EXISTS " + NEW_TABLE_2_DATABASE_CREATE);
        db.execSQL("DROP TABLE IF EXISTS " + NEW_TABLE_3_DATABASE_CREATE);

        onCreate(db);
    }   

下面是我用来创建表的 sqlite 语句:

private static final String ORIGINAL_DATABASE_CREATE = "create table " + VEHICLE_EXPENSE_TABLE_NAME + 
        " (" + KEY_ROW_ID + " integer primary key autoincrement, " + 
        KEY_UNIX_DATE + " integer, " + 
        KEY_DATE + " not null default current_date, " +
        KEY_TIME + " not null default current_time, " + 
        KEY_DESCRIPTION + " text, " + 
        KEY_START_MILE + " integer, " + 
        KEY_END_MILE + " integer, " + 
        KEY_MILES + " text, " + 
        KEY_AMOUNT + " text, " 
        + KEY_PARTY_ID + " integer)";

private static final String NEW_TABLE_1_DATABASE_CREATE = "CREATE TABLE " + PURCHASE_HISTORY_TABLE_NAME + 
        "(" + HISTORY_ORDER_ID_COL + " TEXT PRIMARY KEY, " +
        HISTORY_STATE_COL + " INTEGER, " + 
        HISTORY_PRODUCT_ID_COL + " TEXT, " + 
        HISTORY_DEVELOPER_PAYLOAD_COL + " TEXT, " + 
        HISTORY_PURCHASE_TIME_COL + " INTEGER)";

private static final String NEW_TABLE_2_DATABASE_CREATE = "CREATE TABLE " + PURCHASED_ITEMS_TABLE_NAME + 
        "(" + PURCHASED_PRODUCT_ID_COL + " TEXT PRIMARY KEY, " + 
        PURCHASED_QUANTITY_COL + " INTEGER)";

private static final String NEW_TABLE_3_DATABASE_CREATE = "CREATE TABLE " + TRIAL_LIMIT_TABLE_NAME + 
        "(" + TRIAL_PRODUCT_ID_COL + " TEXT PRIMARY KEY, " + 
        TRIAL_PRODUCT_NAME + " TEXT, " + 
        TRIAL_START_DATE + " INTEGER)";

任何帮助将不胜感激。

谢谢你,凯文

4

2 回答 2

3

onUpgrade()中,您必须对drop现有表(将数据迁移到某个临时数据结构后),然后创建新表(使用数据结构中的旧数据)。如果不是,旧表仍将存在。

如果这不能解决问题,请将您正在使用的确切命令粘贴到db.execSQL()

于 2012-07-27T12:13:37.960 回答
1

修复了我自己的问题。问题是我创建了一个单独的 DB 帮助程序类,它正在访问试图升级的同一个数据库。在这个单独的 DB 助手类中,版本号设置为 1。这个应用程序是我的第一个 Java 和 Android 程序,我设置了 DB 类。我已将所有 DB 类合并到我现在正在升级的类中,现在我的 DB 版本正在按应有的方式更新。如果有人感兴趣,下面是我的最后一节课。

@Override
    public void onCreate(SQLiteDatabase db) {
        Log.w(TAG, "Current db version is " + db.getVersion());

        db.execSQL(VEHICLE_EXPENSE_DATABASE_CREATE);

        db.execSQL(PURCHASE_HISTORY_DATABASE_CREATE);
        db.execSQL(PURCHASE_ITEMS_DATABASE_CREATE);
        db.execSQL(TRIAL_TIME_DATABASE_CREATE);
    }


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

        Log.w(TAG, "Old Version " + oldVersion + " New Version " + newVersion + " db.getVersion is " + db.getVersion());

        if (oldVersion < newVersion) {

            if (oldVersion == 1) {
                db = upgradeTo2(db);
            }
        }
    }

private SQLiteDatabase upgradeTo2(SQLiteDatabase db) {

        db.beginTransaction();
        try {
            db.execSQL(PURCHASE_HISTORY_DATABASE_CREATE);
            db.execSQL(PURCHASE_ITEMS_DATABASE_CREATE);
            db.execSQL(TRIAL_TIME_DATABASE_CREATE);
            db.setTransactionSuccessful();
        } catch (Exception e) {
            Log.w(TAG, "onUpgrade failed");
        } finally {
            db.endTransaction();
        }

        return db;
    }
于 2012-07-28T18:00:56.563 回答