存储过程异常:MySQL Workbench有结果但Java程序ResultSet为空
存储过程在Workbench正常返回数据,Java调用时ResultSet为空的问题解决
问题描述
我在数据库中创建了getIntervento存储过程,在MySQL Workbench中执行可返回多条数据,但调试Java程序时ResultSet为空。以下是相关代码:
原存储过程代码
CREATE DEFINER=`root`@`localhost` PROCEDURE `getIntervento`( IN in_stato TINYINT(1) ) BEGIN DECLARE done INT DEFAULT FALSE; DECLARE numero INT; DECLARE modello VARCHAR(45); DECLARE marca VARCHAR(45); DECLARE costo INT; DECLARE descrizioneComp VARCHAR(45); DECLARE cur CURSOR FOR SELECT i.`numeroRiparazione` ,i.`marca`,i.`modello`, i.`costo`, c.`descrizione` FROM `intervento` i JOIN `necessita` n on i.numeroRiparazione=n.codiceIntervento JOIN `componente` c ON n.codiceComponente=c.codice WHERE pagamento=in_stato; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; DROP TEMPORARY TABLE IF EXISTS `cercaIntervento`; CREATE TEMPORARY TABLE `cercaIntervento` ( `numero` INT, `marca`VARCHAR(45), `modello` VARCHAR(45), `costo` INT, `descrizione` VARCHAR(45) ); SET transaction isolation level read committed; START transaction; OPEN cur; read_loop: LOOP FETCH cur INTO numero, marca, modello, costo,descrizioneComp; IF done THEN LEAVE read_loop; END IF; INSERT INTO `cercaIntervento` VALUES (numero, marca, modello, costo, descrizioneComp); END LOOP; CLOSE cur; SELECT * FROM `cercaIntervento`; COMMIT; END,
原Java调用代码
public List<Intervento> viewIntervento(int n) throws SQLException { Intervento intervento; List<Intervento> allIntervento = new ArrayList<>(); try(CallableStatement cs = connection.conn.prepareCall("{call getIntervento(?)}")){ cs.setInt(1,n); boolean status=cs.execute(); if(status){ ResultSet rs=cs.getResultSet(); while(rs.next()){ int numero=rs.getInt(1); String marca = rs.getString(2); String modello = rs.getString(3); int costo = rs.getInt(4); String descrizione = rs.getString(5); intervento = new Intervento(marca, modello, costo, descrizione, numero); allIntervento.add(intervento); } } }catch (SQLException e) { throw new SQLException("errore durante la lettura: " + e.getMessage()); } return allIntervento; }
问题排查与修复方案
1. 简化存储过程(移除冗余逻辑)
原存储过程使用游标和临时表中转数据完全没必要,反而可能引入隐性问题。直接返回查询结果即可,同时修正末尾多余的逗号:
CREATE DEFINER=`root`@`localhost` PROCEDURE `getIntervento`( IN in_stato TINYINT(1) ) BEGIN SET transaction isolation level read committed; SELECT i.`numeroRiparazione`, i.`marca`, i.`modello`, i.`costo`, c.`descrizione` FROM `intervento` i JOIN `necessita` n ON i.numeroRiparazione = n.codiceIntervento JOIN `componente` c ON n.codiceComponente = c.codice WHERE pagamento = in_stato; END
2. 修复Java代码的结果集处理逻辑
调用存储过程时,CallableStatement可能返回多个结果集或更新计数,需循环处理所有结果集:
public List<Intervento> viewIntervento(int n) throws SQLException { List<Intervento> allIntervento = new ArrayList<>(); try(CallableStatement cs = connection.conn.prepareCall("{call getIntervento(?)}")){ cs.setInt(1, n); boolean hasResultSet = cs.execute(); // 循环处理所有结果集 while (hasResultSet) { ResultSet rs = cs.getResultSet(); while(rs.next()){ int numero = rs.getInt(1); String marca = rs.getString(2); String modello = rs.getString(3); int costo = rs.getInt(4); String descrizione = rs.getString(5); Intervento intervento = new Intervento(marca, modello, costo, descrizione, numero); allIntervento.add(intervento); } // 检查是否存在下一个结果集 hasResultSet = cs.getMoreResults(); } } catch (SQLException e) { throw new SQLException("errore durante la lettura: " + e.getMessage()); } return allIntervento; }
3. 额外验证点
- 确认Java传入的参数
n与Workbench测试时使用的参数值完全一致; - 检查Java程序的数据库连接用户是否拥有
intervento、necessita、componente三张表的查询权限; - 验证数据库连接的环境(如是否连接到正确的数据库实例)与Workbench一致。
内容的提问来源于stack exchange,提问作者user26859885
相关产品推荐
相关产品推荐

