如何向Sqlite数据库表中添加一个新的列,而该列在android中并不存在?

4 人关注

在版本升级时,我想在sqlite数据库表中增加一个新的列,这个列在android中是不存在的。如果这个列已经存在,就不应该改变这个表。在onUpgrade()方法中,我没有删除该表,因为我不想丢失数据。

android
sqlite
Jagadeesh
Jagadeesh
发布于 2013-10-10
3 个回答
Matt
Matt
发布于 2021-10-05
已采纳
0 人赞同

我把一些评论拼凑起来,得到了这个结果。

Cursor cursor = database.rawQuery("SELECT * FROM MY_TABLE", null); // grab cursor for all data
int deleteStateColumnIndex = cursor.getColumnIndex("MISSING_COLUMN");  // see if the column is there
if (deleteStateColumnIndex < 0) { 
    // missing_column not there - add it
    database.execSQL("ALTER TABLE MY_TABLE ADD COLUMN MISSING_COLUMN int null;");

这就故意忽略了数据库的版本号,如果没有的话,就纯粹添加这个列(在我的例子中,版本号对我没有帮助,因为在这个列应该被添加的时候,版本号已经不正常了)。

如果你的表格中没有行,怎么办?
Sunny
Sunny
发布于 2021-10-05
0 人赞同
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // If you need to add a column
    if (newVersion > oldVersion) {
     if(!ColunmExists) {
        db.execSQL("ALTER TABLE foo ADD COLUMN new_column INTEGER DEFAULT 0");
    
我们如何在onCreate()或onUpgrade()本身检查列是否存在?什么是ColunmExists?
简单地对你的表进行查询 cursor.getColumnIndex(String columnName) returns -1 如果列不存在。
ColunmExists 只是一个变量。
你认为在onCreate()或onUpgrade()中为每个版本的升级启动游标并调用和使用它是一个好的编程做法吗?任何更好的解决方案都值得赞赏。
这不会损害你的程序。这对一个应用程序来说是正常的。你只需要在 newVersion>oldVersion 时初始化Cursor。所以它不会每次都被调用。请看编辑的内容。
Sayem
Sayem
发布于 2021-10-05
0 人赞同

I used pragma to find out column existed or not.

fun SupportSQLiteDatabase.safeRunQueryToAddColumn(
tableName: String,
columnName: String,
block: () -> Any) {
    val cursor = query(
        "SELECT count(*) FROM pragma_table_info('$tableName') WHERE name='$columnName'", null)
    val columnExisted = if (cursor.moveToNext()) {
        cursor.getInt(0) == 1 // row found
    } else false
    cursor.close()
    if (!columnExisted) {
        block()
    } else {
        Log.w(
            "ERROR",
            "column add ignored, table : $tableName : column $columnName already existed"