Android sqlite 表更新

Android中Sqlite算是比较常用的了,其中onCreate和onUpgrade这两个方法应该算是最基本的了。说白了onCreate就是建表用的,onUpgrade就是升级表用的。如果说我现在要建一张表那就是

public void onCreate(SQLiteDatabase db) {
  db.execSQL("create table ExcelCell(c_id varchar(40) primary key,"
                    + "c_title varchar(40),"
                    + "c_row varchar(40),"
                    + "c_content text,"
                    + "c_parentId varchar(40),"
                    + "c_rootId varchar(40),"
                    + "c_index varchar(40))");
}

系统运行之后你就可以操作这张表了。但系统ok之后我发现我要加一个remark字段,那就改一下sql呗,于是就有了

public void onCreate(SQLiteDatabase db) {
  db.execSQL("create table ExcelCell(c_id varchar(40) primary key,"
                    + "c_title varchar(40),"
                    + "c_row varchar(40),"
                    + "c_content text,"
                    + "c_parentId varchar(40),"
                    + "c_rootId varchar(40),"
                    + "c_index varchar(40)),"
                    + "remark varchar(40))");
}

但当你刷了一下之后你发现好像操作remark系统就报错了。其实说白了就是系统没有更新你以前的表,因为系统觉得你现在的ExcelCell表和以前的ExcelCell表没啥区别呀,哎,实在忍不了就把原来的卸载了重新装一下apk,一运行,好了,但这个方式好像暴力了一点吧,
如果每次加一个字段就卸载重装,估计谁心里都是草泥马。还好我们有onUpgrade,于是就有了这

public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {  
    db.execSQL("alter table ExcelCell add remark varchar(10)");
}

好了在跑一下,结果发现操作remark还是错,感觉要生气了。其实这是因为onUpgrade的执行是有条件的,那就是它必须检测到新的要更新的数据库操作的版本号要大于当前已存在数据库的版本号,这样才会执行onUpgrade方法。好了,改一下VERSION(假设以前是1,现在就是2),然后在跑一下,操作一下remark字段,发现没问题。感觉好开心。可是用着用着发现又少了一个字段,于是就有了

public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {  
    db.execSQL("alter table ExcelCell add remark varchar(10)");
    db.execSQL("alter table ExcelCell add remark_one varchar(10)");
}

在改一下VERSION(刚才是2,现在改为3),好简单呀,运行一下,你发现又报错了。为什么呢,原来ExcelCell表中已经有remark字段,而新的版本号里面的onUpgrade又执行了一次add remark,那可不是就得报错,于是检测一下字段是否存在吧,于是有了(checkColumnExistsInMaste是拷贝的网上的,具体出自哪不知道了,勿怪)

public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {  
    if(checkColumnExistsInMaster(db,"ExcelCell","remark"))
    {
            db.execSQL("alter table ExcelCell add remark varchar(10)");
    }
    db.execSQL("alter table ExcelCell add remark_one varchar(10)");
}

private boolean checkColumnExistsInMaster(SQLiteDatabase db, String tableName
       , String columnName) {
    boolean result = false ;
    Cursor cursor = null ;
    try{
        cursor = db.rawQuery( "select * from sqlite_master where name = ? and sql like ?"
           , new String[]{tableName , "%" + columnName + "%"} );
        result = null != cursor && cursor.moveToFirst() ;
    }catch (Exception e){
        Log.e(TAG,"checkColumnExists2..." + e.getMessage()) ;
    }finally{
        if(null != cursor && !cursor.isClosed()){
            cursor.close() ;
        }
    }
    return result ;
}

运行一下,发现还是有错,检查一下,原来sqlite_master中只保存了onCreate中create table ExcelCell所添加的字段,可是咋现在的remark是通过alter table ExcelCell add remark varchar(10)添加的,所以还是不行,那就换一种方式吧,条条大路通罗马吗(checkColumnExistInTable是拷贝的网上的,具体出自哪不知道了,勿怪)

public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {  
    if(checkColumnExistInTable(db,"ExcelCell","remark"))
    {
            db.execSQL("alter table ExcelCell add remark varchar(10)");
    }
    db.execSQL("alter table ExcelCell add remark_one varchar(10)");
}

private boolean checkColumnExistInTable(SQLiteDatabase db, String tableName
                , String columnName) {
     boolean result = false ;
        Cursor cursor = null ;
        try{
             cursor = db.rawQuery( "SELECT * FROM " + tableName + " LIMIT 0"
                  , null );
            result = cursor != null && cursor.getColumnIndex(columnName) != -1 ;
        }catch (Exception e){
                Log.e("error","checkColumnExists2..." + e.getMessage()) ;
       }finally{
            if(null != cursor && !cursor.isClosed()){
                cursor.close() ;
           }
      }
      return result ;
}

在跑一下,发现妥妥的,没有问题了。可是觉得老差点意思,明明VERSION就是用来维护版本的,可是我们还要每次都去检测表中是否有当前字段,于是就有了

public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {  
    switch (arg1) {
    case 1:
        db.execSQL("alter table ExcelCell add remark varchar(10)");
    case 2:
        db.execSQL("alter table ExcelCell add remark_one varchar(10)");
    default:
        break;
    }
}

测试一下,没啥问题。这里只是说了添加字段的问题,其实像添加表也是一样的,改一下sql语句即可。

你可能感兴趣的:(android)