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

如何使用Spring SimpleJdbcCall调用Apache Derby存储过程并解决解析错误问题

如何使用Spring SimpleJdbcCall调用Apache Derby存储过程并解决解析错误问题

嘿,我之前也踩过这个坑!问题核心在于Apache Derby不支持Spring SimpleJdbcCall默认生成的参数名 => ?这种命名参数调用语法,它只认位置参数的调用格式,所以才会触发解析错误。咱们一步步来解决:

问题根源

Spring的SimpleJdbcCall默认会尝试用命名参数的方式生成调用语句,也就是你看到的[{call EMPLOYEE_TIME_BY_ID(ID => ?)}],但Derby的存储过程调用语法不支持这种写法,它只接受{call 存储过程名(参数1, 参数2...)}这种位置参数形式。

解决方案一:关闭命名参数功能,改用位置参数绑定

你可以通过关闭元数据自动访问的方式,让Spring生成Derby能识别的位置参数调用语句:

// 初始化SimpleJdbcCall
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
    .withProcedureName("EMPLOYEE_TIME_BY_ID")
    .withoutProcedureColumnMetaDataAccess() // 关键:关闭元数据自动获取,避免生成命名参数语法
    .declareParameters(new SqlParameter("ID", Types.INTEGER)); // 声明输入参数

// 调用存储过程,注意参数顺序要和存储过程定义一致
Map<String, Object> params = new HashMap<>();
params.put("ID", 123); // 这里的键名仅用于绑定,实际按位置传递
Map<String, Object> result = jdbcCall.execute(params);

// 或者更直接的数组传参,完全按位置匹配
// Map<String, Object> result = jdbcCall.execute(123);

配置后,Spring会生成[{call EMPLOYEE_TIME_BY_ID(?)}]这种Derby能正确解析的调用语句。

解决方案二:手动指定符合Derby语法的调用字符串

如果你需要更灵活的控制,可以直接手动指定调用SQL,绕过Spring的自动生成逻辑:

SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
    .withProcedureName("EMPLOYEE_TIME_BY_ID")
    .withCallString("{call EMPLOYEE_TIME_BY_ID(?)}"); // 手动指定Derby兼容的调用语句

// 调用方式和之前一致
Map<String, Object> params = new HashMap<>();
params.put("ID", 123);
Map<String, Object> result = jdbcCall.execute(params);

这种方式更直接,完全由你控制调用语句的格式,不用担心Spring生成不兼容的语法。

额外注意事项

  • 不管用哪种方式,参数顺序一定要和存储过程定义的参数顺序完全一致,因为Derby是按位置识别参数的。
  • 如果你的存储过程有输出参数或者返回结果集,记得用SqlOutParameter或SqlInOutParameter正确声明参数类型。

备注:内容来源于stack exchange,提问作者Robert White

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 17:28:12