#java #spring-boot #sybase
#java #весенняя загрузка #sybase
Вопрос:
Пытаюсь выполнить вызов хранимой процедуры Sybase с помощью JPA @Query. Я следил за информацией, представленной здесь, https://www.baeldung.com/spring-data-jpa-stored-procedures , в качестве ориентира, даже несмотря на то, что информация предназначена для MySQL и именованных параметров. Я знаю, что хранимая процедура работает, так как я могу выполнить ее с помощью клиента DBVis. Я также знаю, что значения хранимой процедуры верны, так как я включил ведение журнала в режиме гибернации и всегда вижу следующий фрагмент перед каждым вызовом :
2020-12-30 13:51:07 TRACE o.h.t.d.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [pub_req_t]
2020-12-30 13:51:07 TRACE o.h.t.d.sql.BasicBinder - binding parameter [2] as [INTEGER] - [1]
@Query выглядит следующим образом :
@Query(value = "call rp_surrogate(?1, ?2);", nativeQuery = true)
int getSurrogateByQueryV1(String surrtype, Integer newsurr );
Объявление хранимой процедуры :
CREATE PROCEDURE dbo.rp_surrogate (
@surrtype char(32),
@newsurr domn_num_id output
)
as begin
Кажется, не имеет значения, что я передаю в параметр ?2 (output), так как он все равно игнорируется. Я пробовал как jconn4, версия 7.0, так и jtds, версия 1.3.1, драйверы JDBC…оба они создают одно и то же исключение :
- jconn4 — Вызвано: com.sybase.jdbc4.jdbc.SybSQLException: неправильный синтаксис рядом с ‘@p0’.
- jtds — Вызвано: java.sql.SQLException: неправильный синтаксис рядом с ‘@P0’.
Стек времени выполнения :
- Пружинный ботинок 2.2.8
- Java 1.8
- Sybase ASE 15
Я пробовал использовать аннотацию @Modifying в сочетании с @Trasactional: думая, что JPA, возможно, будет использовать @P0 в качестве обновленных строк или кода состояния для хранимой процедуры … Нет.
@Modifying
@Query(value = "call rp_surrogate(?1, ?2);", nativeQuery = true)
@Transactional(rollbackFor=Exception.class)
int getSurrogateByQueryV1(String surrtype, Integer newsurr );
Results in : Caused by: com.sybase.jdbc4.jdbc.SybSQLException: Incorrect syntax near '@p0'.
Кроме того, попробовал 4 варианта @Query, все возвращают одно и то же исключение…Некоторые с точкой с запятой, некоторые с вызовом.
@Query(value = "call rp_surrogate(?1, ?2)", nativeQuery = true)
int getSurrogateByQueryV1(String surrtype, Integer newsurr );
Results in : Caused by: java.sql.SQLException: Incorrect syntax near '@P0'.
@Query(value = "call rp_surrogate(?1, ?2);", nativeQuery = true)
int getSurrogateByQueryV2(String surrtype, Integer newsurr );
Results in : Caused by: java.sql.SQLException: Incorrect syntax near '@P0'.
@Query(value = "rp_surrogate(?1, ?2);", nativeQuery = true)
int getSurrogateByQueryV3(String surrtype, Integer newsurr );
Results in : Caused by: java.sql.SQLException: Incorrect syntax near '@P0'.
@Query(value = "rp_surrogate(?1, ?2)", nativeQuery = true)
int getSurrogateByQueryV4(String surrtype, Integer newsurr );
Results in : Caused by: java.sql.SQLException: Incorrect syntax near '@P0'.
Единственное, что я могу сообщить, что работает, это следующее, которое работает, но мы хотели бы иметь чистую / бережливую версию с использованием @Query, поскольку некоторые из этих процедур, которые нам нужно вызвать, имеют довольно большие параметры.
@Override
public int getSurrogateByType(String typeSurrogate) {
EntityManager em = secondaryEntityManager.getObject().createEntityManager();
StoredProcedureQuery query = em.createStoredProcedureQuery("rp_surrogate");
// JDBC : The jconn and jtDS drivers do NOT understand named parameters...we
// MUST use positional...
//query.registerStoredProcedureParameter("surrtype", String.class, ParameterMode.IN );
//query.registerStoredProcedureParameter("newsurr", Long.class, ParameterMode.OUT );
query.registerStoredProcedureParameter(1, String.class, ParameterMode.IN);
query.registerStoredProcedureParameter(2, Integer.class, ParameterMode.OUT);
getLog().error("getSurrogateByType() - Surrogate Type [{}]", typeSurrogate);
query.setParameter(1, typeSurrogate);
try {
query.execute();
} catch (Exception ltheXcp) {
getLog().error("{}() - process failure, with exception(s) : ", this.getClass().getSimpleName(), ltheXcp);
ltheXcp.printStackTrace();
throw ltheXcp;
}
Integer commentCount = (Integer) query.getOutputParameterValue(2);
return commentCount.intValue();
}
Кто-нибудь знает, как выполнить такой вызов с помощью драйвера Sybase и @Query?
Комментарии:
1. можете ли вы создавать запросы непосредственно в Sybase? Вы пробовали, что там работает? У меня всегда были ошибки с sybase, потому что он ожидал имя владельца, например dbo.rp_surrogate()
2. Какой диалект был настроен в приложении?
3. Да, мы можем использовать репозиторий и объекты JPA для извлечения записей из таблиц и тому подобное. Диалект — org.hibernate.dialect.SybaseDialect .
4. Вы пробовали
@Procedure
, как описано здесь , если это имеет какое-либо значение?
Ответ №1:
Собственный запрос Sybase не будет поддерживать «Call» и использовать «exec».
@Query(value = "exec rp_surrogate ?1, ?2 ", nativeQuery = true)
int getSurrogateByQueryV1(String surrtype, Integer newsurr );