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

存储过程异常: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:34:59