2011-03-15 95 views
2

我有一個現有的應用程序發佈,我想將位置coords字段添加到sqlite數據庫。將字段添加到現有的sqlite數據庫

我想知道是否可以做到這一點,而無需在數據庫中創建新表。我不想覆蓋用戶現有的數據庫條目,我只是想爲現有的數據庫條目添加這個新的字段並給它一個默認值。

這可能嗎?

回答

10

是的,

你需要,當你更新表格寫你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次升級爲我工作。

+0

你能否解釋一下這個工作方式,因爲你似乎爲'DATABASE_UPGRADE'調用'create table'兩次?也許第二個應該是'create table DATABASE_TABLE'? – 2011-03-15 18:22:08

+0

非常感謝您的回覆。我會給它一個燒傷! – Stephen 2011-03-15 18:30:22

+0

@ dave.c增加了一些工作原理的細節。 – 2011-03-15 18:36:33

1

您可以使用ALTER TABLE添加列。

ALTER TABLE my_table ADD COLUMN location ...;

1

使用SQLiteOpenHelper的onUpgrade方法來運行「alter table」語句。

相關問題