You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:20:27