原因:应用升级,旧用户安装新版APK时需要更新本地数据库,复制旧数据库的数据到新的数据库,数据库添加了新的表或者新的字段
由于项目没有使用第三方数据库框架,所以使用了原生的方法(超级累,建议还是使用第三方框架,例如郭霖的LitePal ,或者greendao)
在你的初始化database的方法中新建表,SQL语句:
database.execSQL(
"create table if not exists tbl_Appliance(ID INT NULL,RoomID INT NULL,DeviceID INT NULL,SubnetID INT NULL,ApplianceImageName varchar(50),Brightness INT NULL,ApplianceID INT NULL,Channel INT NULL,ApplianceRemark varchar(50),OriginalType INT NULL)");
执行SQL命令,如果不存在则创建表tbl_Appliance,ID是字段, INT 是类型, NULL表示值允许为空(这个可以不写)。
如果新表增加了新的列,需要更新表,并把旧表的数据复制到新表里面可以使用以下语句:
//2018.11.15 tbl_Mood
private static final String CREATE_tbl_Mood_temp = "alter table tbl_Mood rename to tbl_Mood_temp";
private static final String CREATE_tbl_Mood = "create table tbl_Mood(ID INT ,RoomID INT ,MoodID INT ,MoodName varchar(50),LightBool INT ,MoodIconName varchar(50),Ac1Bool INT ,Ac2Bool INT ,FloorBool INT ,DiyBool INT ,AudioBool INT ,CurtainBool INT);";
private static final String INSERT_DATA_MOOD = "insert into tbl_Mood(ID ,RoomID ,MoodID ,MoodName ,LightBool ,MoodIconName ,Ac1Bool ,Ac2Bool ,FloorBool ,DiyBool ,AudioBool ) select ID ,RoomID ,MoodID ,MoodName ,LightBool ,MoodIconName ,Ac1Bool ,Ac2Bool ,FloorBool ,DiyBool ,AudioBool from tbl_Mood_temp";
private static final String DROP_TBL_MOOD = "drop table tbl_Mood_temp";
//2018.11.15 tbl_Mood 更新
database.execSQL(CREATE_tbl_Mood_temp); //第一步将旧表改为临时表
database.execSQL(CREATE_tbl_Mood); //第二步创建新表(新添加的字段或去掉 的字段)
database.execSQL(INSERT_DATA_MOOD); //第三步将旧表中的原始数据保存到新表中以防遗失
database.execSQL(DROP_TBL_MOOD); //第四步删除临时备份表
第一步是将旧表改名为临时表;
第二步是创建新表,新表名改成旧表的名称,用来替代旧表,新表添加的字段写在()里面,例如新表里面有10个字段,那么()里就把10个字段都写进去;
第三步将旧表的数据复制到新表里面,由于旧表只有9个字段,所以复制数据时新表里面的参数就写9个,与旧表的字段一一对应,如果把新表的字段全部写进复制队列里面会抛出数据库异常,“新表有10个columns(列),但只提供了9个value(值)”;
复制数据例子:
INSERT INTO new(name, country)
SELECT name, country FROM old;
异常例子(这个是另外一个表异常截图,表里有17个字段,复制旧表数据时把新增的字段也写进了复制队列):
第四步是删除旧表。
如果旧表和新表的列一样,没有增加或减少字段,那么可以使用以下SQL语句来复制旧表数据到新表:
insert into 新表名称 select *,'' from 旧表名称
这个语句可以省掉添加字段的步骤,可以少写很多字段。 ," 不能省略,表示复制所有的字段。
最后说一句,别用原生方法了,写死人的!!!