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

Java操作SQLite插入NULL值时触发NumberFormatException求助

解决SQLite批量插入赛事数据时的NumberFormatException(输入字符串为"null")

问题根源

你遇到的NumberFormatException核心原因很明确:待插入数据里的未开赛比分不是Java的null对象,而是字符串"null"!原来的判断 s[2] != null会返回true(因为这个字符串"null"本身是有效的Java对象,不是null),代码会强行把字符串"null"转成整数,自然触发异常。

另外还有个隐藏坑:就算你把score1/score2正确设为null,用stmt.setInt()也不行——setInt只能接受int基本类型,无法处理null值,会直接抛出NullPointerException,得用setObject来映射SQL的NULL。

修复方案

我给你一步步调整代码,解决这些问题:

1. 修改比分的判断逻辑

把字符串"null"(包括可能的空字符串、带空格的" null ")都视为null处理,代码改成:

Integer score1 = (s[2] == null || "null".equals(s[2].trim()) || s[2].trim().isEmpty()) 
    ? null : Integer.parseInt(s[2].trim());
Integer score2 = (s[3] == null || "null".equals(s[3].trim()) || s[3].trim().isEmpty()) 
    ? null : Integer.parseInt(s[3].trim());

加trim()是为了兼容数据里可能存在的空格,让逻辑更鲁棒。

2. 用setObject替代setInt处理null值

SQL的NULL需要通过JDBC的setObject方法设置,指定类型为Types.INTEGER,这样Java的null会被正确映射到SQLite的NULL:

stmt.setObject(3, score1, java.sql.Types.INTEGER);
stmt.setObject(4, score2, java.sql.Types.INTEGER);

3. 修复winner计算的NPE风险

当赛事未开赛(dateValue == 0)时,score1和score2都是null,直接比较score1 > score2会抛NullPointerException,所以要先判断赛事状态再处理比分比较:

int winner;
int dateValue = Integer.parseInt(s[4]);
if (dateValue != 0) {
    // 已开赛的情况才比较比分,同时判空避免NPE
    if (score1 != null && score2 != null) {
        if (score1 > score2) {
            winner = 1;
        } else if (score2 > score1) {
            winner = 2;
        } else {
            winner = 0; // 平局
        }
    } else {
        // 理论上已开赛不会有null比分,这里做兜底处理
        winner = 0;
    }
} else {
    winner = 3; // 未开赛
}
stmt.setString(6, Integer.toString(winner)); // 你原来的代码漏了设置winner参数!

注意:原来的代码里没有把winner设置到PreparedStatement中,这会导致参数数量不匹配,我补上了这行关键代码。

完整修复后的代码

void insertFixtures(List<String[]> fixtures) throws SQLException{
    String query = "REPLACE INTO games (team1_id, team2_id, score1, score2, created_at, winner) VALUES (? ,?, ?, ?, ?, ?)";
    // 用try-with-resources自动关闭资源,避免资源泄漏
    try (Connection con = DBConnector.connect();
         PreparedStatement stmt = con.prepareStatement(query)) { 
        for (String[] s : fixtures) {
            try{
                stmt.setString(1, s[0]);
                stmt.setString(2, s[1]);
                
                // 处理比分:字符串"null"或空字符串都视为null
                Integer score1 = (s[2] == null || "null".equals(s[2].trim()) || s[2].trim().isEmpty()) 
                    ? null : Integer.parseInt(s[2].trim());
                Integer score2 = (s[3] == null || "null".equals(s[3].trim()) || s[3].trim().isEmpty()) 
                    ? null : Integer.parseInt(s[3].trim());
                
                // 用setObject设置null值,映射到SQL的NULL
                stmt.setObject(3, score1, java.sql.Types.INTEGER);
                stmt.setObject(4, score2, java.sql.Types.INTEGER);
                
                stmt.setString(5, s[4]);
                
                // 计算winner,避免空指针异常
                int winner;
                int dateValue = Integer.parseInt(s[4]);
                if (dateValue != 0) {
                    if (score1 != null && score2 != null) {
                        if (score1 > score2) {
                            winner = 1;
                        } else if (score2 > score1) {
                            winner = 2;
                        } else {
                            winner = 0;
                        }
                    } else {
                        winner = 0;
                    }
                } else {
                    winner = 3;
                }
                stmt.setString(6, Integer.toString(winner));
                
                stmt.addBatch(); // 用批量执行代替单次execute,提升插入效率
            } catch (NumberFormatException e) {
                e.printStackTrace();
                // 可以在这里添加错误日志,或者跳过无效数据
            }
        }
        stmt.executeBatch(); // 统一执行批量插入
    }
}

额外优化点:用try-with-resources自动关闭连接和Statement,避免手动关闭可能遗漏的资源泄漏问题;改用addBatch()+executeBatch()批量执行插入,比循环里单次execute()效率高很多。

内容的提问来源于stack exchange,提问作者user11242688

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:03:09