我有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是指向表标题行的链接(一对多)。我想编写一种方法来升级这些表。我知道的第一种也是最少的情况是创建第一个和第二个表的临时表副本,创建新结构并将数据插入新结构。
但在这种情况下,所有"id_headers_id"的关系都将丢失。我怎样才能将它们保留在新结构中,同时我希望它们保留为"自动增量"。
SQLiteDatabase.insert 返回新的_id。 首先插入 Headers 表数据,在临时数据结构中创建新_id与_id的映射。
现在,当您填充详细信息表时,请查阅地图以获取旧的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);
}
}