将字段添加到现有的 sqlite 数据库 [英] Adding a field to an existing sqlite database

查看:34
本文介绍了将字段添加到现有的 sqlite 数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经发布了一个现有的应用程序,我想将位置坐标字段添加到 sqlite 数据库.

I have an existing app published and I want to add location coords field to the sqlite database.

我想知道是否可以在不在数据库中创建新表的情况下执行此操作.我不想覆盖用户现有的数据库条目,我只想为现有的数据库条目添加这个新字段并给它一个默认值.

I want to know if it is possible to do this without creating a new table in the database. I don't want to overwrite the users existing database entries, I just want to add this new field for existing database entries and give it a default value.

这可能吗?

推荐答案

是的,

您需要在更新表时编写 onUpgrade() 方法.目前,我使用以下内容创建一个带有新列的新表并复制我当前的所有数据.希望您可以将其调整到您的代码中.

You need to write your onUpgrade() method when you update your table. Currently, I use the following to create a new table with the new column and to copy all my current data over. Hopefully you can adapt this to your code.

@Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion);

            db.beginTransaction();
            try {
                db.execSQL("CREATE TABLE IF NOT EXISTS " + DATABASE_UPGRADE);
                List<String> columns = GetColumns(db, DATABASE_TABLE);
                db.execSQL("ALTER table " + DATABASE_TABLE + " RENAME TO 'temp_" + DATABASE_TABLE + "'");
                db.execSQL("create table " + DATABASE_UPGRADE);
                columns.retainAll(GetColumns(db, DATABASE_TABLE));
                String cols = join(columns, ","); 
                db.execSQL(String.format( "INSERT INTO %s (%s) SELECT %s from temp_%s", DATABASE_TABLE, cols, cols, DATABASE_TABLE));
                db.execSQL("DROP table 'temp_" + DATABASE_TABLE + "'");
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
        }
    }

    public static List<String> GetColumns(SQLiteDatabase db, String tableName) {
        List<String> ar = null;
        Cursor c = null;
        try {
            c = db.rawQuery("select * from " + tableName + " limit 1", null);
            if (c != null) {
                ar = new ArrayList<String>(Arrays.asList(c.getColumnNames()));
            }
        } catch (Exception e) {
            Log.v(tableName, e.getMessage(), e);
            e.printStackTrace();
        } finally {
            if (c != null)
                c.close();
        }
        return ar;
    }

    public static String join(List<String> list, String delim) {
        StringBuilder buf = new StringBuilder();
        int num = list.size();
        for (int i = 0; i < num; i++) {
            if (i != 0)
                buf.append(delim);
            buf.append((String) list.get(i));
        }
        return buf.toString();
    }

这包含 onUpgrade() 和两个辅助方法.DATABASE_UPGRADE 是包含升级数据库的字符串:

This contains onUpgrade() and two helper methods. DATABASE_UPGRADE is a string that contains the upgrade database:

private static final String DATABASE_UPGRADE =
    "notes (_id integer primary key autoincrement, "
    + "title text not null, "
    + "body text not null, "
    + "date text not null, "
    + "edit text not null, "
    + "reminder text, "
    + "img_source text, "
    + "deletion, "
    + "priority)";

快速说明这是如何工作的:

Quick note about how this works:

  1. 检查当前版本的表是否已经存在(它永远不应该),因为在这种情况下不应该调用 onUpgrade().
  2. 由于失败,从当前表中获取列的列表(使用辅助函数 GetColumns()).
  3. 将旧表重命名为 temp_OLDTABLENAME.
  4. 创建新版本的数据库附加列(当前为空).
  5. 从旧版本的数据库中获取所有信息.
  6. 将其插入新数据库
  7. 删除旧表 (temp_OLDTABLENAME).

我尝试编写足够通用的代码,因此我所要做的就是使用附加列更新 DATABASE_UPGRADE,然后它会处理所有其他内容.到目前为止,它已经通过 3 次升级对我有用.

I tried to write this generic enough so all i have to do is update DATABASE_UPGRADE with the additional columns and this handles all the rest. It has worked for me through 3 upgrade so far.

这篇关于将字段添加到现有的 sqlite 数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆