向现有 sqlite 数据库添加字段

发布于 2024-10-21 20:15:38 字数 143 浏览 0 评论 0原文

我已经发布了一个现有的应用程序,我想将位置坐标字段添加到 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.

Is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浪漫之都 2024-10-28 20:15:38

是的,

您需要在更新表时编写 onUpgrade() 方法。目前,我使用以下命令创建一个包含新列的新表,并复制所有当前数据。希望您可以将其适应您的代码。

@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 是一个包含升级数据库的字符串:

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)";

关于其工作原理的快速说明:

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

我尝试编写足够通用的代码,所以我所要做的就是使用附加列更新 DATABASE_UPGRADE,这将处理所有其余的事情。到目前为止,它已经对我进行了 3 次升级。

Yes it is,

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();
    }

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. Check if current version of the table already exists (it never should) as onUpgrade() shouldn't get called in this case.
  2. Since that failed, get the list of columns from the current table (uses helper function GetColumns()).
  3. rename the old table to temp_OLDTABLENAME.
  4. Create the a new version of the database additional columns (currently empty).
  5. get all information from the old version of the database.
  6. insert it into new database
  7. drop the old table (temp_OLDTABLENAME).

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.

寒尘 2024-10-28 20:15:38

您可以使用 ALTER TABLE 添加列。

更改表 my_table 添加列位置 ...;

You can add columns using ALTER TABLE.

ALTER TABLE my_table ADD COLUMN location ...;

舟遥客 2024-10-28 20:15:38

使用 onUpgrade 方法来运行“alter table”语句。

Use the onUpgrade method of the SQLiteOpenHelper to run the "alter table" statements.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文