Чтобы выполнить оператор, эта строка парируется. В этот момент я получаю ошибку анализа, когда она встречается с> . Похоже, что анализатор не имеет ни малейшего представления, как разобраться в => в строке вызова. Так почему же это помещает это в строку вызова только для того, чтобы позже отклонить его? Плохая грамматика SQL [{Call employee_time_by_id (id =>?)}] .
Ошибка возникает в методе org.apache.derby.impl.sql.compile.parserimpl.parsestatement () . Первым параметром этого метода является строка вызовов {call employee_time_by_id (id =>?)} . Это вызывает личный метод, который в конечном итоге бросает исключение с сообщением org.apache.derby.impl.sql.compile.parseexception: встречается ">" в строке 1, столбец 31 . Код ошибки составляет 42x01 .
Я не понимаю, как строка вызова может отформатироваться таким образом, чтобы впоследствии не было проанализирована. Хранящаяся процедура вызывается следующим образом: < /p>
Код: Выделить всё
public JSONArray getClosedPeriodDataMap(String spName, Map inParams) {
SimpleJdbcCall simpleJdbcCall =
jdbcCallFactory.create()
.withProcedureName(spName)
.withNamedBinding()
.returningResultSet("JSONObjectList", new JSONObjectRowMapper());
MapSqlParameterSource source = new MapSqlParameterSource(inParams);
var resultsMap = simpleJdbcCall.execute(source);
JSONArray resultArray = new JSONArray();
resultArray.putAll(resultsMap.get("JSONObjectList"));
return resultArray;
}
Код: Выделить всё
Map params = new HashMap();
SqlParameterValue idValue = SqlParameterHelper.makeIntValue("ID", 1);
params.put("ID", idValue);
request.setParams(params);
Код: Выделить всё
static SqlParameterValue makeIntValue(String name, int value) {
SqlParameter param = new SqlParameter(name, Types.INTEGER);
return new SqlParameterValue(param, value);
}
< /code>
В IN, кажется, правильно связан. Выходной параметр должным образом распознается как параметр возврата. Именно тогда, когда процесс вызова пытается проанализировать созданную вызывающую строку, она запуталась. < /P>
Таблица создается следующим образом: < /p>
CREATE TABLE EMPLOYEE_TIME(
ID INT PRIMARY KEY,
NAME VARCHAR(20) not null,
START_DATE DATE not null ,
END_DATE DATE,
HOURS_WORKED NUMERIC not null
);
< /code>
Процедура, которая всегда должна быть методом Java в Derby Apache, создается следующим образом: < /p>
CREATE PROCEDURE EMPLOYEE_TIME_BY_ID(IN ID INTEGER)
PARAMETER STYLE JAVA
LANGUAGE JAVA
MODIFIES SQL DATA
DYNAMIC RESULT SETS 1
EXTERNAL NAME 'com.something.StoredProcedures.getEmployeeTimeById';
< /code>
Метод (который никогда даже не приближается к тому, что его называют из -за исключения анализа) определяется следующим образом: < /p>
public static class StoredProcedures {
public void getEmployeeTimeById(final int id, ResultSet[] timesheets) throws SQLException {
try (Connection conn = DriverManager.getConnection("jdbc:default:connection");
PreparedStatement ps = conn.prepareStatement("SELECT * FROM DBA.EMPLOYEE_TIME WHERE id = ?")) {
ps.setInt(1, id);
ResultSet results = ps.executeQuery();
timesheets[0] = results;
}
}
< /code>
Кстати, типичная строка вызова Apache Derby будет чем -то вроде < /p>
CallableStatement cs = conn.prepareCall("{ call MY_PROC(?, ?)}");Обратите внимание, что нет => . Неясно, почему эта странная «стрелка» вставлена в строку вызова. Может быть, лучшее решение - суммировать SimplyJdbccall и просто вызовать вызов через обычный JDBC CallableStatement .
Обновление: Оператор вставлен org.springframework.jdbc.core.metadata.genericcallmetadataprovider.namedparameterbindingTouse () , но только тогда, когда данный параметр является названным параметром. Не имеет значения, используется ли метод простой Например, если параметр предоставляется в виде SQLParameter с именем. Любой именованный параметр приведет к тому, что анализатор Apache Derby выпустит исключение, когда он попытается проанализировать оператор => . Возможно, можно было бы переопределить org.springframework.jdbc.core.metadata.callmetadatacontext.createParameterbinding () , чтобы игнорировать привязку с именем и просто возвращать "?" вместо чего -то вроде «id =>? Derbycallmetadataprovider.namedparameterbindingtouse () , который использует метод своего суперкласса GenericCallMetAdatapRovider.namedParameterBindingTouse () , который является виновным, ответственным за инъекцию оператора связывания => . Напротив, реализации Sybase и SQLServer этого метода создают что -то вроде «ID?» . Я не знаю, сможет ли Дерби справиться с этим синтаксисом, поэтому, вероятно, лучше избегать привязки именованного параметра в целом с помощью Apache Derby, если в какой -то момент проанализир не улучшен для обработки => в строке вызовов или в DerbycallmetAdataprovider.namedParameterbindingTouse () , что вызывает что -то, что его собственный parser может PARSE. Назван параметры из моего тестового кода и попробуйте еще раз. Полезный ответ ниже из @Life8888888 не использует именованные параметры. Похоже, что Apache Derby не может обрабатывать названные параметры, поскольку они являются мощной особенностью и одной из обоснований для использования классов JDBC Spring.
Подробнее здесь: https://stackoverflow.com/questions/795 ... lejdbccall