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

指定周可用游戏全量入库异常:代码仅插入6条数据的排查

问题排查:指定周游戏存入数据库仅插入6条数据的原因

需求

编写代码将指定周(weekNumber)的所有可用游戏存入数据库。

提供的代码

public static void main(String[] args) {
    try {
        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/nflpickem",
                "root", "root");

        System.out.println("Create USER/GAME (bases)");

        String[] users = {"red", "blue"};
        String[] grps = {"bronze", "gold", "silver"};

        int gameID = 10000;
        int pid = 10000;
        int weekNumber = 1;

        for (int i = 0; i < users.length; i++) {
            for (int y = 0; y < grps.length; y++) { //modified the loop condition for 'grps' to avoid index out of bounds
                String sql = "INSERT INTO PICKS VALUES (";
                sql = sql + ++pid + ",";
                sql = sql + "'" + users[i] + "',";
                sql = sql + "'" + grps[y] + "',";
                sql = sql + "" + ++gameID + ",";
                sql = sql + "" + weekNumber + ",";
                if (i < users.length/2) { // add all picks for half of the users
                    sql = sql + "'ATL')";
                } else if (i == 1 && y == 1) { // add some picks for specific user
                    sql = sql + "'BUF')";
                } else { // add no picks for users
                    sql = sql + "'NO')";
                }

                System.out.println(sql);

                try {
                    conn.createStatement().execute(sql);

                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
                
            }

        }
         
        System.out.println("Table USER created!");
    } catch (Exception e) {
        System.out.println("oops:" + e);
    }
}

问题现象

运行代码后仅存入6条数据,无论该周可用游戏数量多少,始终只能插入6条。

已尝试方案

  • 调整周与gameID关联
  • 拆分查询
  • 用HashSet存储gameID
  • 强制关联week1数据
    以上方案均未解决,求助排查原因。

原因分析

问题根源非常直接:当前代码完全没有和指定周的可用游戏数据产生关联。代码里的循环是基于固定的users数组(长度2)和grps数组(长度3)做嵌套遍历,2*3=6次循环,每次循环插入1条数据,所以必然只会生成6条记录。

代码里的gameID是手动自增的固定值,不是从数据库或其他数据源获取的该周实际可用游戏ID,自然不会根据周内游戏数量动态生成数据。

修复思路及示例代码

  1. 先查询指定周的所有可用游戏ID列表
  2. 遍历用户、分组、游戏的笛卡尔积,为每个组合插入记录
  3. 使用PreparedStatement避免SQL注入,同时提升执行效率
  4. 注意资源的关闭,防止连接泄漏

修改后的示例代码:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class GamePicker {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement insertStmt = null;
        PreparedStatement gameQueryStmt = null;
        ResultSet rs = null;

        try {
            // 1. 建立数据库连接
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/nflpickem",
                    "root", "root");
            System.out.println("连接数据库成功");

            int weekNumber = 1;
            String[] users = {"red", "blue"};
            String[] grps = {"bronze", "gold", "silver"};
            int pid = 10000;

            // 2. 查询指定周的所有可用游戏ID
            List<Integer> gameIds = new ArrayList<>();
            String gameSql = "SELECT game_id FROM games WHERE week_number = ?";
            gameQueryStmt = conn.prepareStatement(gameSql);
            gameQueryStmt.setInt(1, weekNumber);
            rs = gameQueryStmt.executeQuery();
            while (rs.next()) {
                gameIds.add(rs.getInt("game_id"));
            }

            if (gameIds.isEmpty()) {
                System.out.println("该周没有可用游戏");
                return;
            }

            // 3. 准备插入语句(使用PreparedStatement防止SQL注入)
            String insertSql = "INSERT INTO PICKS (pid, user, grp, game_id, week_number, pick) VALUES (?, ?, ?, ?, ?, ?)";
            insertStmt = conn.prepareStatement(insertSql);

            // 4. 遍历用户、分组、游戏,插入所有组合
            for (String user : users) {
                for (String grp : grps) {
                    for (int gameId : gameIds) {
                        // 设置参数
                        insertStmt.setInt(1, ++pid);
                        insertStmt.setString(2, user);
                        insertStmt.setString(3, grp);
                        insertStmt.setInt(4, gameId);
                        insertStmt.setInt(5, weekNumber);
                        // 根据用户设置pick值,保留原逻辑
                        if (user.equals("red")) {
                            insertStmt.setString(6, "ATL");
                        } else if (user.equals("blue") && grp.equals("gold")) {
                            insertStmt.setString(6, "BUF");
                        } else {
                            insertStmt.setString(6, "NO");
                        }
                        // 添加到批处理(可选,提升效率)
                        insertStmt.addBatch();
                    }
                }
            }
            // 执行批处理插入
            insertStmt.executeBatch();
            System.out.println("成功插入 " + (users.length * grps.length * gameIds.size()) + " 条数据");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 5. 关闭资源
            try {
                if (rs != null) rs.close();
                if (gameQueryStmt != null) gameQueryStmt.close();
                if (insertStmt != null) insertStmt.close();
                if (conn != null) conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

说明

  • 假设存储周游戏的表名为games,包含game_id和week_number字段,你需要根据实际表结构调整查询语句
  • 使用PreparedStatement替代字符串拼接SQL,避免SQL注入风险,同时重复利用语句提升性能
  • 加入了资源关闭逻辑,防止数据库连接泄漏
  • 插入逻辑改为基于实际查询到的游戏ID列表,数据量会随周内游戏数量动态变化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 09:28:10