SimpleJdbcCall не работает для хранимой функции

Я пытаюсь выполнить хранимую функцию в DB2 из Java. Функция и код, который ее вызывает, очень похожи на код из примера документации Spring https://docs.spring.io/spring/docs/current/spring-framework-reference/html/jdbc.html#jdbc.-simple-jdbc-call-3. Вот объявление функции:

CREATE FUNCTION ST_CLIENT_SEGMENT( p_oib VARCHAR(11) )
    RETURNS VARCHAR(10)
    NO EXTERNAL ACTION

Вот код:

//version1
SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(jdbcTemplate)
    .withSchemaName("VLIB").
    .withFunctionName("ST_CLIENT_SEGMENT")
SqlParameterSource in = new MapSqlParameterSource().addValue("p_oib", "123");
return simpleJdbcCall.executeFunction(String.class, in);

//version2
SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(jdbcTemplate)
    .withSchemaName("VLIB")
    .withFunctionName("ST_CLIENT_SEGMENT");
simpleJdbcCall.declareParameters(new SqlParameter("p_oib", Types.VARCHAR));
return simpleJdbcCall.executeFunction(String.class, "123");

//the same exception
//Caused by: java.sql.SQLException: [SQL0440] Routine ST_CLIENT_SEGMENT in VLIB not found with specified parameters.

кто-нибудь знает, почему это произошло? Когда я вызываю функцию из моего SQL-клиента, все работает нормально.


person Ivan    schedule 14.12.2016    source источник
comment
Многие базы данных не позволяют вызывать функции изолированно (потому что тогда они были бы просто хранимыми процедурами), вы можете попробовать использовать функцию, например, в запросе на выборку.   -  person Mark Rotteveel    schedule 14.12.2016
comment
@MarkRotteveel Как я уже сказал, он работает из моего клиента SQL (тот же пользователь). значения vlib.st_client_segment('123'); или выберите VLIB.ST_CLIENT_SEGMENT('123') из SYSIBM.SYSDUMMY1;   -  person Ivan    schedule 14.12.2016
comment
Вы предполагаете, что это эквивалентно тому, что создается SimpleJdbcCall. Это вполне может быть не так (смотря на код, он на самом деле строит побег JDBC: {? = call vlib.st_client_segment(?)}, который затем должен быть преобразован драйвером JDBC. Вполне может быть, что драйвер JDBC DB2 поддерживает только выполнение хранимых процедур с Экранирование вызова JDBC, поэтому он может сгенерировать SQL, недопустимый для вызова функции.   -  person Mark Rotteveel    schedule 14.12.2016


Ответы (1)


Мой коллега нашел решение. Похоже, это проблема DB2 http://www.itjungle.com/fhg/fhg102506-story01.html. Я пробую другой SQL, который также дал мне исключение

jdbcTemplate.queryForObject("values vlib.ST_CLIENT_SEGMENT(?)", new Object[] {oib}, String.class);
//Caused by: java.sql.SQLException: [SQL0418] Use of parameter marker not valid.

После этого изменения все работает нормально

jdbcTemplate.queryForObject("values vlib.ST_CLIENT_SEGMENT( CAST( ? as CHAR) )", new Object[] {oib}, String.class);
person Ivan    schedule 14.12.2016