#jdbc #snowflake-cloud-data-platform #callable-statement
#jdbc #платформа облачных данных snowflake #вызываемая инструкция
Вопрос:
Мы написали хранимую процедуру в Snowflake, которая вставляет значения в таблицу и возвращает первичный ключ. Я пытаюсь вызвать эту хранимую процедуру, используя ее драйвер JDBC.
final Connection connection = getJdbcTemplate().getDataSource().getConnection();
final CallableStatement callableStatement = connection.prepareCall("{call REWARD.sp_issue_reward(?, ?, ?)}");
callableStatement.setLong(1, reward.getClientSeq());
callableStatement.setLong(2, reward.getUserUniqueId());
callableStatement.registerOutParameter(3, Types.INTEGER); // throws SQLFeatureNotSupportedException
callableStatement.executeUpdate();
connection.prepareCall
Возвращает экземпляр SnowflakeCallableStatementV1.class
. Проблема в том, что этот класс имеет следующую реализацию для регистрации выходного параметра:
/*
The Snowflake database does not accept OUT or INOUT parameters, so the registerOutParameter functions and the get
functions (which get values of OUT parameters) will remain not implemented)
*/
public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
Пример определения хранимой процедуры, которая используется:
create or replace procedure sp_issue_reward(CLIENT_SEQ float,
USER_SEQ float)
returns float not null
language javascript
called on null input
volatile
as
$$
var REWARD_ID = 1;
var insertStatement = snowflake.createStatement({
sqlText: "INSERT INTO REWARD.REWARD_CPY ("
"reward_seq, "
"client_seq, "
"user_seq) "
"VALUES (?, ?, ?)",
binds: [REWARD_ID, CLIENT_SEQ, USER_SEQ]
})
.execute();
return REWARD_ID;
$$;
Как получить выходные данные хранимой процедуры с помощью драйвера Snowflake JDBC?
Результаты такие же и для этой хранимой процедуры:
CREATE or replace PROCEDURE testSp()
RETURNS VARCHAR
LANGUAGE javascript
AS
$$
var rs = "Test"
return rs;
$$;
Комментарии:
1. Каково определение этой хранимой процедуры?
2. Я обновил вопрос определением хранимой процедуры.
Ответ №1:
Проблема здесь:
callableStatement.executeUpdate();
Когда вы вызываете хранимую процедуру из JDBC, вы не выполняете обновление. Вы выполняете запрос, даже несмотря на то, что SP выполняет обновление.
Хранимая процедура вернет одну строку с одним столбцом для результата. Вы можете получить его следующим образом:
Statement stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("call TEST_JDBC()");
while (rs.next()) {
System.out.println(rs.getString(1));
}
Вы, конечно, можете сделать что-то более сложное, используя подготовленные инструкции, но используйте ExecuteQuery.
Комментарии:
1. Спасибо. Я хотел бы добавить, что мне пришлось удалить фигурные скобки из
connection.prepareCall(..)
функции. Похоже, что Snowflake раньше не любила фигурные скобки,call
и именно поэтомуSimpleJdbcCall.class
не работала.