Android SQLite插入报错:不存在man列且字段值顺序异常求助
解决SQLite插入XML数据时字段顺序错误及表列不存在问题
从你的错误日志和代码来看,有两个核心问题需要解决:字段值匹配混乱,以及表结构不匹配的报错,下面一步步帮你搞定:
一、修复XML属性值的错位问题
你当前通过索引getAttributeValue(0/1/2)获取属性值的方式存在隐患——XML标准里属性的顺序是不固定的,解析器返回的顺序可能和你写的不一样,这就导致你拿到的值完全对应错了(日志里path=dwd就是明证,dwd明明是第二个record的man属性值)。
替换成按属性名获取值的方式,才能保证对应关系正确:
// 原来的按索引取值(错误) // String path = _xml.getAttributeValue(0); // String woman = _xml.getAttributeValue(1); // String man = _xml.getAttributeValue(2); // 改成按属性名取值(正确) String path = _xml.getAttributeValue(null, "path"); String woman = _xml.getAttributeValue(null, "woman"); String man = _xml.getAttributeValue(null, "man");
二、解决"table mytable has no column named man"报错
这个问题的根源是:SQLiteOpenHelper的onCreate方法只会在数据库第一次创建时执行一次。如果你是先创建了没有man列的表,后来才在代码里加上这个列,那么设备上的旧数据库文件并不会自动更新结构。
有两种解决方式:
- 测试阶段快速方案:直接卸载APP,重新安装。旧的数据库文件会被删除,重新安装后会执行最新的
onCreate代码,创建带有man列的表。 - 正式环境规范方案:通过版本升级来更新表结构:
- 把
DBHelper构造器里的版本号从1改成2:super(context, "myDB", null, 2); // 版本号从1→2 - 完善
onUpgrade方法,添加列更新逻辑:
这样下次启动APP时,系统会自动检测版本变化,执行表结构更新,不需要卸载APP。@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 如果旧版本小于2,就添加man列 if (oldVersion < 2) { db.execSQL("ALTER TABLE mytable ADD COLUMN man text;"); } }
- 把
三、额外优化小建议
- 每次插入前清空
ContentValues:虽然你当前的代码覆盖了三个key的值,但循环中如果忘记覆盖某个key,就会带入上一次的数据,建议在values.put(...)前加上values.clear(); - 批量插入用事务:如果XML里的record数量较多,把插入逻辑放在事务里能大幅提升效率:
db.beginTransaction(); try { int eventType = _xml.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { if ((eventType == XmlPullParser.START_TAG) && (_xml.getName().equals("record"))) { values.clear(); String path = _xml.getAttributeValue(null, "path"); String woman = _xml.getAttributeValue(null, "woman"); String man = _xml.getAttributeValue(null, "man"); values.put("path", path); values.put("woman", woman); values.put("man", man); db.insert("mytable", null, values); Log.d(LOG_TAG, "success"); } eventType = _xml.next(); } db.setTransactionSuccessful(); } catch (XmlPullParserException e) { Log.e("Test", e.getMessage(), e); } catch (IOException e) { Log.e("Test", e.getMessage(), e); } finally { _xml.close(); db.endTransaction(); }
内容的提问来源于stack exchange,提问作者Sopelus
相关产品推荐
相关产品推荐

