如何将Integers和Doubles正确存入ContentValues?CSV转SQLite空值问题
解决CSV导入SQLite时数字类型存为Null的问题
我之前也遇到过类似的坑——CSV里的内容全是字符串格式,直接往ContentValues里塞的话,SQLite没法自动把字符串转成整数/浮点数,结果就存成Null了。核心解法就是先做类型检测与转换,再根据数据库列的类型对应存入ContentValues,具体步骤如下:
1. 先写工具方法判断字符串能否转成数字
因为CSV读取的所有值都是String,我们需要通过try-catch来验证它是否符合整数或浮点数的格式:
// 判断字符串是否为有效整数 private boolean isInteger(String str) { if (str == null || str.trim().isEmpty()) return false; try { Integer.parseInt(str.trim()); return true; } catch (NumberFormatException e) { return false; } } // 判断字符串是否为有效浮点数(包含Double、Float) private boolean isDouble(String str) { if (str == null || str.trim().isEmpty()) return false; try { Double.parseDouble(str.trim()); return true; } catch (NumberFormatException e) { return false; } }
2. 结合数据库列类型处理每一行数据
你肯定知道自己的SQLite表哪些列是Integer、哪些是Double、哪些是String,要么硬编码列类型,要么动态查询表结构(更灵活),然后针对每一列做转换:
方式一:硬编码列类型(适合表结构固定的场景)
假设你的表有id(INTEGER)、price(DOUBLE)、product_name(TEXT)三列,CSV的列顺序和表一致:
// csvRow是拆分后的一行CSV数据,比如["1", "99.9", "Apple"] ContentValues values = new ContentValues(); // 处理id列(Integer类型) String idStr = csvRow[0].trim(); if (isInteger(idStr)) { values.put("id", Integer.parseInt(idStr)); } else { // 无法转换时的处理:设为Null或默认值,根据业务需求来 values.putNull("id"); // 也可以抛出异常提醒数据错误:throw new IllegalArgumentException("Invalid integer for id: " + idStr); } // 处理price列(Double类型) String priceStr = csvRow[1].trim(); if (isDouble(priceStr)) { values.put("price", Double.parseDouble(priceStr)); } else { values.putNull("price"); } // 处理product_name列(String类型) values.put("product_name", csvRow[2].trim()); // 插入数据库 db.insert("your_table_name", null, values);
方式二:动态查询表结构(适合表结构可能变化的场景)
通过SQLite的PRAGMA table_info获取表的列名和类型,再动态处理:
// 先查询表结构 List<String> columnNames = new ArrayList<>(); List<String> columnTypes = new ArrayList<>(); Cursor tableCursor = db.rawQuery("PRAGMA table_info(your_table_name)", null); while (tableCursor.moveToNext()) { columnNames.add(tableCursor.getString(tableCursor.getColumnIndex("name"))); columnTypes.add(tableCursor.getString(tableCursor.getColumnIndex("type"))); } tableCursor.close(); // 处理CSV行数据 ContentValues values = new ContentValues(); for (int i = 0; i < csvRow.length; i++) { String valueStr = csvRow[i].trim(); String colName = columnNames.get(i); String colType = columnTypes.get(i).toUpperCase(); switch (colType) { case "INTEGER": if (isInteger(valueStr)) { values.put(colName, Integer.parseInt(valueStr)); } else { values.putNull(colName); } break; case "DOUBLE": case "REAL": // SQLite里REAL对应Java的Double if (isDouble(valueStr)) { values.put(colName, Double.parseDouble(valueStr)); } else { values.putNull(colName); } break; case "TEXT": values.put(colName, valueStr); break; // 其他类型如BLOB等按需扩展 default: values.put(colName, valueStr); break; } } db.insert("your_table_name", null, values);
3. 注意几个细节
- 空字符串处理:CSV里的空值可能是
"",这时候要判断是存Null还是默认值,比如整数列可以设为0,根据业务需求调整。 - 本地化问题:如果CSV里的浮点数用逗号做小数点(比如欧洲地区),要先把逗号替换成点再转换:
valueStr.replace(",", ".")。 - 科学计数法:
Double.parseDouble()可以处理"1e3"这类格式,但Integer.parseInt()不行,所以如果列是Integer类型,要额外判断这种情况。
内容的提问来源于stack exchange,提问作者Scooltr
相关产品推荐
相关产品推荐

