如何调用 Spring JPA 函数并在对象中返回结果
Posted
技术标签:
【中文标题】如何调用 Spring JPA 函数并在对象中返回结果【英文标题】:How to invoke Spring JPA function and return result in an object 【发布时间】:2021-12-29 18:19:20 【问题描述】:我在包 PACKAGE_A 中有无法修改的函数 FUNC。我想从 Spring JPA 存储库中调用此函数,但我不知道该怎么做。
功能:
FUNCTION FUNC(
RESULT_COLUMN_A OUT NUMBER,
RESULT_COLUMN_B OUT NUMBER,
RESULT_COLUMN_C OUT VARCHAR
) RETURN NUMBER AS
BEGIN
SELECT COL_1, COL_2, COL_3
INTO RESULT_COLUMN_A, RESULT_COLUMN_B, RESULT_COLUMN_C
FROM DATABASE_TABLE;
RETURN 0;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN -1;
END;
函数已针对这个问题进行了修改,这不是一个工作场景,但重要的是函数返回三列。
到目前为止我的代码:
@Repository
public class FunctionRepository
@Autowired
private JdbcTemplate jdbcTemplate;
public FuncResponse findFunctionResult()
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withCatalogName("PACKAGE_A") //package name
.withFunctionName("FUNC");
//First parameter is function output parameter type.
FuncResponse response = jdbcCall.executeFunction(FuncResponse.class);
return response;
class FuncResult
@Column(name = "RESULT_COLUMN_A")
String resultColumnA;
String resultColumnB;
String resultColumnC;
当我尝试运行代码时,出现以下异常:
java.sql.SQLException: Missing IN or OUT parameter at index:: 1
at oracle.jdbc.driver.OraclePreparedStatement.processCompletedBindRow(OraclePreparedStatement.java:2033) ~[ojdbc11-21.3.0.0.jar:21.3.0.0.0]
更新: 我已经用以下代码更新了,我最初的错误是响应不是数字,而是一个类。所以更新的代码是这样的:
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withCatalogName("PACKAGE_A") //package name
.withFunctionName("FUNC")
.declareParameters(new SqlParameter("RESULT_COLUMN_A ", Types.NUMERIC))
.declareParameters(new SqlParameter("RESULT_COLUMN_B ", Types.NUMERIC))
.declareParameters(new SqlParameter("RESULT_COLUMN_C ", Types.VARCHAR))
.withoutProcedureColumnMetaDataAccess();
//First parameter is function output parameter type.
Long response = jdbcCall.executeFunction(Long.class);
if(response == 0)..
问题是它仍然失败并出现异常
java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
at org.springframework.jdbc.core.metadata.CallMetaDataContext.matchInParameterValuesWithCallParameters(CallMetaDataContext.java:610)
【问题讨论】:
一个函数可以有 OUT 或 IN OUT 参数,但这是不好的编码习惯。一个函数应该有一个返回值并且没有输出参数。如果你需要一个函数的多个值,你应该使用一个过程。此外,您在我的代码中缺少指定输入参数和输出参数的部分。 【参考方案1】:听起来您缺少该函数的 in 参数。这是我的一个项目的一个例子。此外,每个函数只能返回一个值,但看起来您正试图在上面的函数中返回多个值。您可能需要仔细检查。
/*this is at the top of my class. */
private JdbcTemplate jdbcTemplate;
static final String ORCL_SCHEMA = "scott";
static final String ORCL_PKG = "BIGPACKAGE";
@Override
public String validateProgCode(String prog, String coas, Date trnsdate)
SimpleJdbcCall call = new SimpleJdbcCall(jdbcTemplate)
.withSchemaName(ORCL_SCHEMA)
.withCatalogName(ORCL_PKG)
.withFunctionName("F_VALIDATEPROGCODE")
.declareParameters(new SqlParameter("L_PROG", OracleTypes.VARCHAR))
.declareParameters(new SqlParameter("L_COAS", OracleTypes.VARCHAR))
.declareParameters(new SqlParameter("TRNSDATE", OracleTypes.DATE));
Map<String, Object> inParams = new HashMap<>();
inParams.put("L_PROG", prog);
inParams.put("L_COAS", coas);
inParams.put("TRNSDATE", trnsdate);
String validInd = call.executeFunction(String.class, inParams);
return validInd;
这是oracle函数的摘录
FUNCTION F_ValidateProgCode (L_PROG VARCHAR2, L_COAS VARCHAR2, trnsDate DATE) RETURN
VARCHAR2 IS
....
end;
【讨论】:
不,我返回一个值,数字,但我有三个 OUT 参数。我已经更新了问题以上是关于如何调用 Spring JPA 函数并在对象中返回结果的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data JPA:查询如何返回非实体对象或对象列表?
如何从 Spring Data JPA GROUP BY 查询中返回自定义对象
如何响应 Spring RestController 返回 ManyToOne 双向 JPA 实体对象?