簡體   English   中英

將字段添加到現有sqlite數據庫

[英]Adding a field to an existing sqlite database

我已經發布了現有應用程序,我想將位置coords字段添加到sqlite數據庫。

我想知道是否可以在不在數據庫中創建新表的情況下執行此操作。 我不想覆蓋用戶現有的數據庫條目,我只想為現有的數據庫條目添加這個新字段並給它一個默認值。

這可能嗎?

是的,

更新表時需要編寫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次升級為我工作。

您可以使用ALTER TABLE添加列。

ALTER TABLE my_table ADD COLUMN location ...;

使用SQLiteOpenHelper的onUpgrade方法運行“alter table”語句。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM