Android sqliteテーブルの更新

9802 ワード

AndroidではSqliteがよく使われていますが、onCreateとonUpgradeの2つの方法が最も基本的なはずです.はっきり言って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をもう一度実行したので、それは間違いを報告しなければならないのではないかということで、フィールドが存在するかどうかを検出したのではないでしょうか.
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_マスターにはonCreateでcreate table ExcelCellが追加したフィールドしか保存されていませんが、現在のremarkはalter table ExcelCell add remark varchar(10)で追加されているので、やはりだめです.では、別の方法にしましょう.
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文を変更すればいいです.