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

Java使用JDBC调用MySQL存储过程返回空结果集问题求助

问题原因

你编写的存储过程通过OUT输出参数返回计算结果,本身没有执行直接返回结果集的SELECT语句,因此调用后通过getResultSet()无法拿到有效数据,这不是存储过程编写遗漏,是JDBC取值方式错误。

解决方案

可根据使用场景二选一:

方案1:保留现有存储过程,修改JDBC调用逻辑

直接从CallableStatement读取注册的OUT参数值即可,不需要获取结果集:

CallableStatement lCall = getConnection().prepareCall( "{call getTotal(?,?)}" );
lCall.setTimestamp( 1, new Timestamp( System.currentTimeMillis() - 600000 ));
lCall.registerOutParameter( 2, Types.DOUBLE );
lCall.execute();
// 直接读取第二个输出参数的值
Double volume = lCall.getDouble(2);
// 处理SQL NULL的情况:当无匹配记录时SUM返回NULL,getDouble默认返回0,如需区分可判断
if (lCall.wasNull()) {
    return BigDecimal.ZERO; // 可按业务逻辑调整空值处理规则
}
return BigDecimal.valueOf(volume);

方案2:修改存储过程,直接返回结果集

如果你需要通过ResultSet读取结果,可以去掉OUT参数,让存储过程直接返回查询结果:

修改后的存储过程

CREATE DEFINER=`root`@`localhost` PROCEDURE `getTotal`( IN pSince TIMESTAMP )
BEGIN
    SELECT SUM( quantity ) AS pVolume FROM db.table WHERE orderTime > pSince;
END

对应的JDBC调用代码

CallableStatement lCall = getConnection().prepareCall( "{call getTotal(?)}" );
lCall.setTimestamp( 1, new Timestamp( System.currentTimeMillis() - 600000 ));
ResultSet lResults = lCall.executeQuery();
if (lResults.next()) {
    return lResults.getBigDecimal("pVolume");
}
return BigDecimal.ZERO;
补充说明

你之前调用executeQuery()报错的原因是,该方法要求调用的SQL必须返回至少一个结果集,而使用OUT参数的存储过程没有返回结果集,因此会被判定为写操作触发报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 13:45:05