#java #oracle #spring-jdbc #dto
#java #Oracle #spring-jdbc #dto
Вопрос:
У меня есть функция Oracle с именем GET_RISK_GROUP.
Когда я пытаюсь вызвать эту функцию:
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withSchemaName("NEWIB")
.withCatalogName("PKG_ONLINE_IB_PC_OPERATIONS")
.withFunctionName("GET_RISK_GROUP");
SqlParameterSource source = new MapSqlParameterSource().addValue("P_TAX_NUMBER", taxNumber);
jdbcCall.executeFunction(String.class, source);
Я получаю исключение:
2020-09-11 15:40:25.692 ERROR 1276 --- [nio-8698-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException for SQL [{? = call GET_RISK_GROUP()}]; SQL state [99999]; error code [17041]; Missing IN or OUT parameter at index:: 1; nested exception is java.sql.SQLException: Missing IN or OUT parameter at index:: 1] with root cause
Не удалось найти какое-либо решение. Есть идеи? Из-за этой проблемы я изменил свой код на:
jdbcTemplate.execute(
con -> {
CallableStatement cs = con.prepareCall("{? = call NEWIB.PKG_ONLINE_IB_PC_OPERATIONS.GET_RISK_GROUP(?)}");
cs.registerOutParameter(1, Types.NVARCHAR); // or whatever type your function returns.
// Set your arguments
cs.setString(2, taxNumber);
return cs;
},
(CallableStatementCallback<String>) cs -> {
cs.execute();
String result = cs.getString(1);
return resu< // Whatever is returned here is returned from the jdbcTemplate.execute method
}
);
Это работает нормально.
Ответ №1:
Имея опыт в этом, я мог бы только сказать, чтобы просто внести некоторые стандартные изменения, а затем попробовать, потому что тот же код работает так, как вы сказали, работает на моей машине. Точно не помню, но в одном из вопросов SO упоминалось, что драйвер jdbc может иметь значение.
Я добавил withoutProcedureColumnMetaDataAccess
это, потому что SimpleJdbcCall
мне нравится очень часто запрашивать метаданные сведений о столбце, и чтобы избежать проблем с производительностью в будущем, когда у нас будет больше таких вызовов, желательно добавить это.
Для вызова функции нам также необходимо зарегистрировать (как вы сделали с CallableStatement
) или объявить его в качестве первого параметра, который будет действовать как возвращаемый тип для.
Я надеюсь, что приведенное ниже работает ,
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withSchemaName("NEWIB")
.withCatalogName("PKG_ONLINE_IB_PC_OPERATIONS")
.withFunctionName("GET_RISK_GROUP")
.withoutProcedureColumnMetaDataAccess()
.declareParameters(new SqlOutParameter("return",Types.VARCHAR),
new SqlParameter("p_tax_number", Types.VARCHAR));
// add value to the paramaters
SqlParameterSource parameterMap = new MapSqlParameterSource().addValue("p_tax_number", taxNumber);
// call
String result = jdbcCall.executeFunction(String.class, source);
Постскриптум
Если не работает, не могли бы вы опубликовать тело функции в вопросе или выполнить приведенный ниже запрос и вставить результат здесь
select object_name,argument_name,position,data_type,data_length,in_out
from user_arguments
where OBJECT_NAME ='GET_RISK_GROUP'
and Package_name='PKG_ONLINE_IB_PC_OPERATIONS'