使用Spring中的示例,我试图从mySQL函数返回一个值。我一直得到错误的Can't set IN parameter for return value of stored function call;
。
我创建了一个工作良好的mySQL函数(在MySQL工作台中运行)。我编写了一个SimpleJdbcCall
语句,按照Spring示例设置参数,但始终得到这个错误。如果我将函数转换为一个过程,代码可以工作,我只需从结果集中检索返回值。
我以https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch13s05.html第13.5.8节作为参考。
CREATE FUNCTION `ScenarioRegistration`(
environment VARCHAR(45),
username VARCHAR(15),
scenario_name VARCHAR(45)) RETURNS int(11)
两个SELECT语句,后面跟着一个INSERT
RETURN scenario_id; // The inserted id
Java代码:
SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(getJdbcTemplate())
.withFunctionName("ScenarioRegistration")
.withoutProcedureColumnMetaDataAccess();
simpleJdbcCall.addDeclaredParameter(new SqlParameter("environment"
,Types.VARCHAR));
simpleJdbcCall.addDeclaredParameter(new SqlParameter("username"
,Types.VARCHAR));
simpleJdbcCall.addDeclaredParameter(new SqlParameter("scenario_name"
,Types.VARCHAR));
SqlParameterSource parameters = new MapSqlParameterSource()
.addValue("environment", environment)
.addValue("username", username)
.addValue("scenario_name", scenario);
simpleJdbcCall.setReturnValueRequired(true);
Integer scenario_id = simpleJdbcCall.executeFunction(
Integer.class, parameters);
我想要做的就是把新插入的场景的id还给我。我得到的是:SQL [{? = call scenarioregistration(?, ?)}]; Can't set IN parameter for return value of stored function call.
我发现有趣的是,它使用了我的三个输入值,并将它们更改为一个输出值和两个输入值。
有人教我这个问题以及如何解决这个问题吗?
谢谢,
史蒂文。
发布于 2019-01-28 22:57:28
关于你的答案,我会参考最新的医生在这里。Spring似乎试图推断输出,因为您没有明确指定输出。
根据上面的文档,有两种使用SimpleJdbcCall
调用所需函数的有效方法
推断参数
因为您已经指定了withoutProcedureColumnMetaDataAccess
,所以Spring将不会查看和查看输入/输出对您的函数是什么。如果您想要轻松,只需不要指定它,您应该能够:
SqlParameterSource parameters = new MapSqlParameterSource()
.addValue("environment", environment)
.addValue("username", username)
.addValue("scenario_name", scenario);
Integer scenarioId = new SimpleJdbcCall(getJdbcTemplate())
.withFunctionName("ScenarioRegistration")
.executeFunction(Integer.class, parameters);
显式参数
如果您想让withoutProcedureColumnMetaDataAccess
因任何原因关闭,您可以这样做:
Integer scenarioId = new SimpleJdbcCall(getJdbcTemplate)
.withFunctionName("ScenarioRegistration")
.withoutProcedureColumnMetaDataAccess()
.useInParameterNames("environment", "username", "scenario_name")
.declareParameters(
new SqlOutParameter("scenario_id", Types.NUMERIC),
new SqlParameter("environment", Types.VARCHAR),
new SqlParameter("username", Types.VARCHAR),
new SqlParameter("scenario_name", Types.VARCHAR)
).executeFunction(Integer.class, parameters);
注意:在本例中,order似乎是。应该首先声明output
参数,然后再声明名为IN
的参数。也就是说,参数?
的顺序在[{? = call scenarioregistration(?, ?, ?)}]
__中是序数)
NamedParameterJdbcTemplate
解决方案
调用函数的另一种方法是通过实际的JDBC调用。假设情况下,这可以避免使用SimpleJdbcCall
的微调带来的痛苦。
Integer scenarioId = namedParameterJdbcTemplate.queryForObject(
"SELECT ScenarioRegistration(:environment, :username, :scenario_name)",
parameters,
Integer.class);
https://stackoverflow.com/questions/54414425
复制