0

私は2つのテーブルを持っています。名前付きのヘッダーとテキスト付きの詳細:

create table Headers (_id integer primary key autoincrement, name string);
create table Details (_id integer primary key autoincrement, id_headers integet, text string);

id_headers は、テーブルのヘッダー行 (1 対多) へのリンクです。これらのテーブルをアップグレードする方法を書きたいと思います。私が知っている最初で最も少ないケースは、1番目と2番目のテーブルの一時テーブルのコピーを作成し、新しい構造を作成し、新しい構造にデータを挿入することです。

ただし、この場合、すべての「id_headers から _id」への関係が失われます。それらを新しい構造に保持するにはどうすればよいですか。同時に、それらを「自動インクリメント」として保持したいのです。

4

1 に答える 1

0

SQLiteDatabase.insertは、新しい_idを返します。最初にHeadersテーブルデータを挿入し、一時データ構造の_idに対する新しい_idのマッピングを作成します。

ここで、Detailsテーブルにデータを入力するときに、マップで古いid_headers値を調べて、新しいid_headers値を取得します。

private void migrate(SQLiteDatabase db){
    ArrayList<Header> oldHeaders = new ArrayList<Header>();
    ArrayList<Detail> oldDetails = new ArrayList<Detail>)();
    HashMap<Long,Long> idMap = new HashMap<Long,Long>();

    Cursor oldHeadersCurs = db.query("Headers", null, null, null, null, null, null);
    oldHeadersCurs.moveToFirst();

    //store the old header records
    while (!oldHeadersCurs.isAfterLast()){
        long oldId = oldHeadersCurs.getLong(oldHeadersCurs.getColumnIndex("_id"));
        String name = oldHeadersCurs.getString(oldHeadersCurs.getColumnIndex("name"));
        oldHeaders.put(new Header(oldId,name));

        oldHeadersCurs.moveToNext();
    }

    //delete the headers table
    db.execSQL("DROP TABLE Headers");
    //create the new headers table
    db.execSQL(CREATE_NEW_HEADERS_TABLE_STMT);

    //insert the header records capturing the new id
    for (Header header : oldHeaders){
        ContentValues cv = new ContentValues();
        cv.put("name", header.getName());
        long newId = db.insert("Headers", null, cv);
        idMap.put(header.getId(), newId); //mapping the old _id to the new 
    }

    //store the old detail records
    Cursor oldDetailsCurs = db.query("Details", null, null, null, null, null, null);
    oldDetailsCurs.moveToFirst();
    while (!oldDetailsCurs.isAfterLast()){
        //btw text is a data type in sqlite, you need to rename this column
        String text = oldDetailsCurs.getString(oldDetailsCurs.getColumnIndex("text"));
        long oldHeaderId = oldDetailsCurs.getLong(oldDetailsCurs.getColumnIndex("id_headers"));
        oldDetails.put(new Detail(text,oldHeaderId));
        oldDetails.moveToNext();
    }

    //recreate details table
    db.execSQL("DROP TABLE Details");
    db.execSQL("CREATE_NEW_DETAILS_TABLE_STMT");

    //insert the new detail records using the id map
    for (Detail detail : oldDetails){
        ContentValues cv = new ContentValues();
        cv.put("text",detail.getText());
        cv.put("id", idMap.get(detail.getHeaderId())); //retrieving the new _id based on the old
        db.insert("Details", null, cv);
    }
}
于 2012-12-13T20:20:38.790 に答える