如何通过Spring JPA调用Oracle包下带OUT参数的函数并返回结果
Oracle包函数Spring JdbcTemplate调用解决方案
问题根源
你遇到的两次报错分别对应以下核心错误:
- 第一次
Missing IN or OUT parameter报错是因为未声明函数的3个OUT参数,也未指定函数本身的返回值类型 - 第二次
ArrayIndexOutOfBoundsException报错有三个诱因:- 使用
SqlParameter声明OUT参数,该类型仅对应IN入参,OUT参数必须用SqlOutParameter声明 - 加了
withoutProcedureColumnMetaDataAccess关闭元数据自动读取后,未声明函数本身的返回值参数 - 声明参数的名称末尾多了多余空格,和函数定义的参数名不匹配
- 使用
正确实现代码
1. 定义结果封装类
public class FuncResponse { // 函数本身的返回值:0成功/-1无数据 private Integer returnCode; private Long resultColumnA; private Long resultColumnB; private String resultColumnC; // 自行补充getter、setter、无参构造方法 }
2. 调整Repository调用逻辑
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlReturnParameter; import org.springframework.jdbc.core.simple.SimpleJdbcCall; import org.springframework.stereotype.Repository; import java.sql.Types; import java.util.Collections; import java.util.Map; @Repository public class FunctionRepository{ @Autowired private JdbcTemplate jdbcTemplate; public FuncResponse findFunctionResult() { SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate) .withCatalogName("PACKAGE_A") .withFunctionName("FUNC") // 第一个参数必须声明函数本身的返回值 .declareParameters(new SqlReturnParameter("RETURN_VALUE", Types.NUMERIC)) // 按函数定义顺序声明3个OUT参数,不要加多余空格 .declareParameters(new SqlOutParameter("RESULT_COLUMN_A", Types.NUMERIC)) .declareParameters(new SqlOutParameter("RESULT_COLUMN_B", Types.NUMERIC)) .declareParameters(new SqlOutParameter("RESULT_COLUMN_C", Types.VARCHAR)) .withoutProcedureColumnMetaDataAccess(); // 函数无入参,传入空Map Map<String, Object> resultMap = jdbcCall.execute(Collections.emptyMap()); FuncResponse response = new FuncResponse(); // 从返回结果中提取返回值和OUT参数 response.setReturnCode(((Number) resultMap.get("RETURN_VALUE")).intValue()); response.setResultColumnA(((Number) resultMap.get("RESULT_COLUMN_A")).longValue()); response.setResultColumnB(((Number) resultMap.get("RESULT_COLUMN_B")).longValue()); response.setResultColumnC((String) resultMap.get("RESULT_COLUMN_C")); return response; } }
可选优化
如果不想手动声明所有参数,可以去掉withoutProcedureColumnMetaDataAccess配置,Spring会自动读取Oracle的参数元数据,只要保证参数名称和函数定义完全一致即可。
内容的提问来源于stack exchange,提问作者2dor
相关产品推荐
相关产品推荐

