MySQL按部门统计师生数的存储过程getNumbers创建与调用问题
问题排查与修正方案
现存代码核心问题
- 存储过程命名不符合需求规范:要求定义的存储过程名为
getNumbers,当前代码定义为getNumber,存在命名偏差。 - 存储过程内部逻辑存在根本性错误:
- 未将统计结果赋值给定义的两个OUT输出参数,错误使用会话变量
@dept_name做无意义赋值,未实现计数结果输出。 - 未使用传入的部门名称入参做数据过滤,WHERE条件嵌入的学生数统计子查询仅判断对应部门是否存在学生记录,无实际筛选效果,会全表遍历所有符合子查询判定的行,无法实现指定部门的计数。
- 仅对instructor表做了无效查询,完全未统计对应部门的学生数量,无法给
student_count输出参数赋值。
- 未将统计结果赋值给定义的两个OUT输出参数,错误使用会话变量
- Java端调用存在参数映射错误:被注释的旧代码尝试注册索引为3、4的输出参数,但存储过程总共仅包含3个参数(1个入参、2个出参),会触发参数越界异常。
修正后的MySQL存储过程代码
(需切换到database_4数据库下执行)
-- 清理旧版本同名存储过程,避免创建冲突 DROP PROCEDURE IF EXISTS getNumbers; DELIMITER $$ -- 严格对齐需求的参数结构:1个输入参数,2个输出参数 CREATE PROCEDURE getNumbers( IN input_dept_name VARCHAR(20), OUT ins_count INT, OUT student_count INT ) BEGIN -- 统计匹配部门的教师数量,直接赋值给输出参数 SELECT COUNT(*) INTO ins_count FROM instructor WHERE dept_name = input_dept_name; -- 统计匹配部门的学生数量,直接赋值给输出参数 SELECT COUNT(*) INTO student_count FROM student WHERE dept_name = input_dept_name; END$$ DELIMITER ;
MySQL环境验证步骤:
- 执行上述存储过程创建语句
- 运行测试调用语句:
CALL getNumbers('Computer Science', @teacher_cnt, @student_cnt); SELECT @teacher_cnt AS 对应部门教师数, @student_cnt AS 对应部门学生数;- 核对返回值和表内实际计数是否一致,确保存储过程功能正常。
Java端代码修正要点
- 将存储过程调用语句中的过程名从
getNumber改为getNumbers,否则会抛出存储过程不存在的SQL异常。 - 移除错误的参数注册逻辑,保持3个参数的顺序映射:索引1为入参(部门名称),索引2、3为出参(教师数、学生数),核心修正片段如下:
String dept_name = bufRead.readLine(); CallableStatement cStmt = conn.prepareCall("{CALL getNumbers(?,?, ?)}"); // 绑定输入参数:部门名称 cStmt.setString(1, dept_name); // 注册两个输出参数 cStmt.registerOutParameter(2, Types.INTEGER); cStmt.registerOutParameter(3, Types.INTEGER); cStmt.execute(); // 读取输出参数值的逻辑保持原有实现即可 int instructor_count = cStmt.getInt(2); int student_count = cStmt.getInt(3); - 不需要添加额外的输出参数注册,避免出现参数索引越界的问题。
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

