首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SimpleJdbcCall用于MySql函数的输出“不能为存储函数调用的返回值设置IN参数”

SimpleJdbcCall用于MySql函数的输出“不能为存储函数调用的返回值设置IN参数”
EN

Stack Overflow用户
提问于 2019-01-29 05:34:08
回答 1查看 1.5K关注 0票数 1

使用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节作为参考。

代码语言:javascript
运行
复制
CREATE FUNCTION `ScenarioRegistration`(
  environment VARCHAR(45),
  username VARCHAR(15),
  scenario_name VARCHAR(45)) RETURNS int(11)

两个SELECT语句,后面跟着一个INSERT

代码语言:javascript
运行
复制
RETURN scenario_id; // The inserted id

Java代码:

代码语言:javascript
运行
复制
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.

我发现有趣的是,它使用了我的三个输入值,并将它们更改为一个输出值和两个输入值。

有人教我这个问题以及如何解决这个问题吗?

谢谢,

史蒂文。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-29 06:57:28

关于你的答案,我会参考最新的医生在这里。Spring似乎试图推断输出,因为您没有明确指定输出。

根据上面的文档,有两种使用SimpleJdbcCall调用所需函数的有效方法

推断参数

因为您已经指定了withoutProcedureColumnMetaDataAccess,所以Spring将不会查看和查看输入/输出对您的函数是什么。如果您想要轻松,只需不要指定它,您应该能够:

代码语言:javascript
运行
复制
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因任何原因关闭,您可以这样做:

代码语言:javascript
运行
复制
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的微调带来的痛苦。

代码语言:javascript
运行
复制
Integer scenarioId = namedParameterJdbcTemplate.queryForObject(
    "SELECT ScenarioRegistration(:environment, :username, :scenario_name)", 
    parameters, 
    Integer.class);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54414425

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档