Вызов хранимой процедуры и регистрация выходного параметра с помощью драйвера JDBC

#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 не работала.