Я пытаюсь использовать класс SimpleJdbcCall
для вызова функций в пакете Oracle, но каждый вызов игнорирует первый входной параметр.
Мой код выглядит так:
SimpleJdbcCall call = new SimpleJdbcCall(jdbcTemplate.getJdbcTemplate())
.withSchemaName("MY_SCHEMA")
.withCatalogName("MY_PACKAGE")
.withFunctionName("MY_FUNCTION")
.withoutProcedureColumnMetaDataAccess()
.declareParameters(new SqlParameter("FIRST_ARGUMENT", Types.VARCHAR), new SqlParameter("SECOND_ARGUMENT", Types.VARCHAR));
SqlParameterSource params = new MapSqlParameterSource().addValue("FIRST_ARGUMENT", "VALUE1").addValue("SECOND_ARGUMENT", "VALUE2");
Integer result = call.executeFunction(Integer.class, params);
с моей функцией:
FUNCTION MY_FUNCTION(FIRST_ARGUMENTvarchar2, SECOND_ARGUMENTvarchar2) RETURN number;
В трассировке стека отображаются ошибки такого типа:
org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback; bad SQL grammar [{? = call MY_SCHEMA.MY_PACKAGE.MY_FUNCTION(?)}];
Параметр был удален. Вызов другой функции только с одним параметром вызывает похожую ошибку:
org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback; bad SQL grammar [{? = call MY_SCHEMA.MY_PACKAGE.MY_OTHER_FUNCTION()}];
Я попытался отладить код Spring, spring-boot-starter-jdbc:2.0.1.RELEASE
(тоже 2.0.0
), и я наткнулся на этот код в классе org.springframework.jdbc.core.metadata.CallMetaDataContext
при составлении вызова:
if (isFunction() || isReturnValueRequired()) {
callString = "{? = call " +
(StringUtils.hasLength(catalogNameToUse) ? catalogNameToUse + "." : "") +
(StringUtils.hasLength(schemaNameToUse) ? schemaNameToUse + "." : "") +
procedureNameToUse + "(";
parameterCount = -1;
}
else {
callString = "{call " +
(StringUtils.hasLength(catalogNameToUse) ? catalogNameToUse + "." : "") +
(StringUtils.hasLength(schemaNameToUse) ? schemaNameToUse + "." : "") +
procedureNameToUse + "(";
}
for (SqlParameter parameter : this.callParameters) {
if (!(parameter.isResultsParameter())) {
if (parameterCount > 0) {
callString += ", ";
}
if (parameterCount >= 0) {
callString += createParameterBinding(parameter);
}
parameterCount++;
}
}
callString += ")}";
Если я понял код, первый параметр будет всегда опущен, я прав?
У кого-нибудь был успех в этой ситуации?
M. Deinum прав, и возвращаемый параметр тоже должен быть указан, я ожидал, что Spring автоматически добавит его при работе с функциями.
Мой код сейчас:
SimpleJdbcCall call = new SimpleJdbcCall(jdbcTemplate.getJdbcTemplate())
.withSchemaName("MY_SCHEMA")
.withCatalogName("MY_PACKAGE")
.withFunctionName("MY_FUNCTION")
.withoutProcedureColumnMetaDataAccess()
.declareParameters(new SqlOutParameter("return",Types.INTEGER)
,new SqlParameter("FIRST_ARGUMENT", Types.VARCHAR)
,new SqlParameter("SECOND_ARGUMENT", Types.VARCHAR));
SqlParameterSource params = new MapSqlParameterSource().addValue("FIRST_ARGUMENT", "VALUE1").addValue("SECOND_ARGUMENT", "VALUE2");
Integer result = call.executeFunction(Integer.class, params);