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

Spring调用存储过程报Parameter number 2 is not an OUT parameter错误

问题:Spring调用MySQL存储过程报错“Parameter number 2 is not an OUT parameter”

错误日志

ERROR | 2024-02-28 12:43:23 | [http-/127.0.0.1:8881-1] impl.ProductDAOImpl (ProductDAOImpl.java:702)
- Exception caught for getStockCount Parameter number 2 is not an OUT parameter 
java.sql.SQLException: Parameter number 2 is not an OUT parameter   
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)  
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)   
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)   
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)   
at com.mysql.cj.jdbc.CallableStatement.checkIsOutputParam(CallableStatement.java:643)   
at com.mysql.cj.jdbc.CallableStatement.registerOutParameter(CallableStatement.java:1714)    
at com.mysql.cj.jdbc.CallableStatement.registerOutParameter(CallableStatement.java:1722)

场景说明

直接在MySQL数据库中调用存储过程calculate_stock_count可正常执行;同一代码逻辑调用其他存储过程无异常,但调用该存储过程时,错误出现在callStmt.registerOutParameter(2, java.sql.Types.INTEGER);行。

相关代码

public Integer getStockCount(String partNumber){
    Integer stockCount = null;    
    String query = "{CALL calculate_stock_count(?, ?)}";        
    Connection connection = null;
    CallableStatement callStmt = null;
    
    try {
        connection = this.jdbcTemplate.getDataSource().getConnection();        
        callStmt = connection.prepareCall(query);        
        callStmt.setString(1, partNumber);        
        callStmt.registerOutParameter(2, java.sql.Types.INTEGER);        
        callStmt.execute();        
        stockCount = callStmt.getInt(2);        
    } catch (SQLException e) {
        logger.error("Exception caught for getStockCount " + e.getMessage(), e);
    } finally {
        try {
            if(callStmt != null){
                callStmt.close();
            }
            if(connection != null){
                connection.close();
            }
        } catch (SQLException e) {
            logger.error("Exception caught in getStockCount while closing the connection" + e.getMessage(), e);
        } finally{
            if(connection != null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    logger.error("Exception caught in getStockCount while closing the connection" + e.getMessage(), e);
                }
            }
        }
    }
    return stockCount;
}

错误原因分析

  • 存储过程定义不匹配:代码中默认第二个参数是OUT类型,但实际calculate_stock_count的第二个参数可能不是OUT/INOUT类型,或者参数顺序、数量与代码预期不符。
  • 驱动版本兼容性:部分MySQL JDBC驱动版本对存储过程参数的解析存在差异,可能错误识别参数的输入输出类型。
  • 调用语法偏差:使用{CALL ...}格式调用时,占位符需与存储过程定义的参数类型、顺序完全对应,否则会触发参数类型不匹配错误。

解决方法

  1. 核对存储过程定义
    执行SHOW CREATE PROCEDURE calculate_stock_count;查看参数定义:

    • 如果第二个参数不是OUT/INOUT类型,而是存储过程通过结果集返回数据,需修改代码逻辑:
      callStmt.setString(1, partNumber);
      ResultSet rs = callStmt.executeQuery();
      if(rs.next()){
          stockCount = rs.getInt(1);
      }
      
    • 如果参数顺序或数量不符,调整代码中registerOutParameter的索引值和调用语句的占位符数量。
  2. 验证驱动版本
    确保MySQL JDBC驱动版本与服务器版本匹配(如MySQL 8.0对应mysql-connector-java 8.x),避免版本不兼容导致的参数解析问题。

  3. 优化资源管理
    使用try-with-resources语法自动管理连接和Statement,避免重复关闭资源的冗余代码:

    public Integer getStockCount(String partNumber){
        Integer stockCount = null;    
        String query = "{CALL calculate_stock_count(?, ?)}";        
        try (Connection connection = this.jdbcTemplate.getDataSource().getConnection();
             CallableStatement callStmt = connection.prepareCall(query)) {        
            callStmt.setString(1, partNumber);        
            callStmt.registerOutParameter(2, java.sql.Types.INTEGER);        
            callStmt.execute();        
            stockCount = callStmt.getInt(2);        
        } catch (SQLException e) {
            logger.error("Exception caught for getStockCount " + e.getMessage(), e);
        }
        return stockCount;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 21:04:56