如何将新列添加到资产文件夹中的现有数据库?

时间:2014-07-16 07:26:21

标签: android android-sqlite sqliteopenhelper

我有一个应用程序使用现有的sqlite数据库并将我的数据库放在android应用程序的资产文件夹中。现在我需要将新列添加到数据库表之一。我用谷歌搜索并找到了一些问题和答案,但没有一个问题和答案,我需要在表格上添加新栏目,有些数据我不能丢失它们。我附上了我的代码如下:

公共类ExternalDbOpenHelper扩展了SQLiteOpenHelper {

    public static final int DATABASE_NEW_VERSION = 1;
public static final int DATABASE_OLD_VERSION = 1;

public static String DB_PATH;

private static String TABALE_NAME = "font";
private static String FONT_ID = "_id";
private static String FONT_TYPE = "font_type";
private static String FONT_SIZE = "font_size";

public static String DB_NAME;
public SQLiteDatabase database;
public final Context context;

public SQLiteDatabase getDb() {
    return database;
}

public ExternalDbOpenHelper(Context context, String databaseName) {
    super(context, databaseName, null, DATABASE_NEW_VERSION);
    this.context = context;

    String packageName = context.getPackageName();

    DB_PATH = String.format("//data//data//%s//databases//", packageName);
    DB_NAME = databaseName;
    openDataBase();
}


public void createDataBase() {
    boolean dbExist = checkDataBase();
    if (!dbExist) {
        this.getReadableDatabase();
        try {
            copyDataBase();
        } catch (IOException e) {
            Log.e(this.getClass().toString(), "Copying error");
            throw new Error("Error copying database!");
        }
    } else {
        Log.i(this.getClass().toString(), "Database already exists");
    }
}

private boolean checkDataBase() {
    SQLiteDatabase checkDb = null;
    try {
        String path = DB_PATH + DB_NAME;
        checkDb = SQLiteDatabase.openDatabase(path, null,
                SQLiteDatabase.OPEN_READONLY);
    } catch (SQLException e) {
        Log.e(this.getClass().toString(), "Error while checking db");
    }
    if (checkDb != null) {
        checkDb.close();
    }
    return checkDb != null;
}

private void copyDataBase() throws IOException {

    InputStream externalDbStream = context.getAssets().open(DB_NAME);

    String outFileName = DB_PATH + DB_NAME;

    OutputStream localDbStream = new FileOutputStream(outFileName);

    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = externalDbStream.read(buffer)) > 0) {
        localDbStream.write(buffer, 0, bytesRead);
    }
    localDbStream.close();
    externalDbStream.close();

}

public SQLiteDatabase openDataBase() throws SQLException {
    String path = DB_PATH + DB_NAME;
    if (database == null) {
        createDataBase();
        database = SQLiteDatabase.openDatabase(path, null,
                SQLiteDatabase.OPEN_READWRITE);
    }
    return database;
}

@Override
public synchronized void close() {
    if (database != null) {
        database.close();
    }
    super.close();
}

@Override
public void onCreate(SQLiteDatabase db) {


}

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

}


public int updateFont(int i, String fontName, int p) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues font = new ContentValues();
    font.put(FONT_TYPE, fontName);
    font.put(FONT_SIZE, p);

    String whereClause = FONT_ID + " LIKE ?";
    String[] whereArgs = new String[] { String.valueOf(i) };

    db.update(TABALE_NAME, font, whereClause, whereArgs);
    return db.update(TABALE_NAME, font, whereClause, whereArgs);
    }
}

2 个答案:

答案 0 :(得分:1)

有几种方法,但它们都是从增加DATABASE_NEW_VERSION开始的。

然后,您的onUpgrade()方法将在版本低于DATABASE_NEW_VERSION指定版本的设备上调用。如果您发现自己随着时间的推移进行了多次更改,可以通过查看传递给此方法的oldVersion来检查设备是否是多个版本。

通用解决方案(如果您开始重命名表,列并通常重新映射数据)只是从数据库/表中读取“旧数据”并将其存储在ArrayList等等。然后DROP旧表,CREATE新表,然后INSERT数据。

但是,如果您只是添加新列,则可以使用以下命令完成:

ALTER TABLE {tableName} ADD COLUMN {columnName} {type};

ALTER TABLE语法here

答案 1 :(得分:0)

首先,您需要将表的内容保存到游标中。然后使用更新的列创建一个新数据库并放入光标中的值。