Spring框架SimpleJdbcCall能否调用带默认参数的Oracle存储过程?
问题描述
我在Oracle数据库中创建了一个带有默认参数的存储过程:
procedure cool_procedure( i_id in number , i_number in varchar2 , i_check in number default 1 , i_commit in number := GLOBALS.commit_yes , o_result out number );
我希望使用Spring的SimpleJdbcCall调用该存储过程,且不传入i_check和i_commit参数,尝试了以下代码:
var jdbcCall = simpleJdbcCallFactory.create(jdbcTemplate) .withSchemaName("SCHEMA") .withCatalogName("CATALOG") .withProcedureName("cool_procedure") .withoutProcedureColumnMetaDataAccess() .declareParameters( new SqlParameter("i_id", Types.NUMERIC), new SqlParameter("i_name", Types.VARCHAR), new SqlParameter("i_check", Types.NUMERIC), new SqlParameter("i_commit", Types.NUMERIC), new SqlOutParameter("o_result", Types.NUMERIC) ); var paramMap = new MapSqlParameterSource() .addValue("i_id", id) .addValue("i_name", name); var out = new LinkedCaseInsensitiveMap<>(); out.putAll(jdbcCall.execute(paramMap));
但执行时提示缺少必填参数,请问是否可以不在MapSqlParameterSource的paramMap中添加i_check和i_commit参数?
解决方案
可以实现不传入这两个带默认值的参数,需要调整SimpleJdbcCall的配置:
移除默认参数的显式声明
当你在declareParameters里显式声明i_check和i_commit后,SimpleJdbcCall会认定它们是必须传入的参数,忽略存储过程本身的默认值配置。直接移除这两个参数的声明即可:declareParameters( new SqlParameter("i_id", Types.NUMERIC), new SqlParameter("i_number", Types.VARCHAR), // 注意:原代码参数名`i_name`与存储过程的`i_number`不匹配,必须修正 new SqlOutParameter("o_result", Types.NUMERIC) );开启命名参数绑定(推荐)
开启命名参数绑定能让Oracle更准确地识别哪些参数使用默认值,避免位置匹配错误。通过withNamedBinding()方法开启:var jdbcCall = simpleJdbcCallFactory.create(jdbcTemplate) .withSchemaName("SCHEMA") .withCatalogName("CATALOG") .withProcedureName("cool_procedure") .withoutProcedureColumnMetaDataAccess() .withNamedBinding() .declareParameters( new SqlParameter("i_id", Types.NUMERIC), new SqlParameter("i_number", Types.VARCHAR), new SqlOutParameter("o_result", Types.NUMERIC) );修正参数名映射
确保MapSqlParameterSource中的参数名与存储过程定义完全一致:var paramMap = new MapSqlParameterSource() .addValue("i_id", id) .addValue("i_number", name);
调整后,调用存储过程时会自动使用i_check和i_commit的默认值,无需手动传入。
内容的提问来源于stack exchange,提问作者Linkovschik
相关产品推荐
相关产品推荐

