我在一个包中有一个存储过程,它在同一个包中定义了三个不同的方法签名。它们只有几个参数(每个参数调用下一个具有一些默认值)。为简洁起见,我过度简化了列表列表。在我打电话的程序中,我有大约55个字段。
我正在使用名为“MapSqlParameterSource”的Spring类来定义我提供的字段值:
SqlParameterSource params = new MapSqlParameterSource()
.addValue("pi_session_id", piSessionId)
.addValue("pi_site_id", piSiteId)
.addValue("pi_address_id", piAddressId)
.addValue("po_status_cd", null)
.addValue("po_status_mg", null);
我正在使用一个简单的jdbc调用来定义我想要调用的存储过程:
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withSchemaName("myschema")
.withCatalogName("address_package")
.withProcedureName("p_post_address");
然后我用这个电话执行程序:
Map<String, Object> resultsMap = jdbcCall.execute(params);
我通常会将结果注销,而我正在开发这些结果。
for (String key : resultsMap.keySet()) {
logger.info("p_post_address - Key: " + key + " object: " + resultsMap.get(key));
}
然后我像这样访问输出字段:
String statusMessage = (String) resultsMap.get("po_status_mg");
BigDecimal statsCd = (BigDecimal) resultsMap.get("po_status_cd");
这适用于没有超载的程序!但是,当我调用此特定过程时,它会给我这个错误:
org.springframework.dao.InvalidDataAccessApiUsageException:无法确定正确的呼叫签名 - “P_POST_ADDRESS”的多个程序/功能/签名
然后我试图变得棘手,并确切地指定应该使用哪些参数来调用存储过程,以便它可以匹配我想要的重载方法。
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withSchemaName("myschema")
.withCatalogName("address_package")
.withProcedureName("p_post_address");
jdbcCall.addDeclaredParameter(new SqlParameter("pi_session_id", OracleTypes.NUMBER));
jdbcCall.addDeclaredParameter(new SqlParameter("pi_site_id", OracleTypes.VARCHAR));
jdbcCall.addDeclaredParameter(new SqlParameter("pi_address_id", OracleTypes.NUMBER));
jdbcCall.addDeclaredParameter(new SqlOutParameter("po_status_cd", OracleTypes.NUMBER));
jdbcCall.addDeclaredParameter(new SqlOutParameter("po_status_mg", OracleTypes.VARCHAR));
这导致了同样的错误。
org.springframework.dao.InvalidDataAccessApiUsageException:无法确定正确的呼叫签名 - “P_POST_ADDRESS”的多个程序/功能/签名
我最终发现我需要添加此选项:
jdbcCall.withoutProcedureColumnMetaDataAccess();
这有效!但我不明白为什么。
有人可以解释为什么你需要添加声明的参数addDeclaredParameter
并调用withoutProcedureColumnMetaDataAccess
吗?