Недопустимый индекс при попытке вызвать простую ПРОЦЕДУРУ Oracle из Java

Следующий блок SQL успешно отображает «Y» или «N» при вызове в зависимости от того, выполняется ли процедура для рабочей базы данных или нет.

DECLARE
  v_is_prod VARCHAR2(1);
BEGIN

  FDS_APPS.FDS_USR_SEC_PKG2.IS_RUNNING_IN_PRODUCTION2(v_is_prod);
  dbms_output.put_line('v_is_prod=' || v_is_prod);
END;

Я пытаюсь вызвать эту процедуру из Java (это мой первый вызов). Для этого вопроса, пожалуйста, не обращайте внимания на то, что это, вероятно, должна быть функция, которая возвращает char, а не параметр varchar2 (1) с одним выходом. Я делаю детские шаги.

Это мой код Java:

public String isRunningInProduction() throws DaoException {
        
        LoggerUtil.info("Start calling [" + IS_RUNNING_IN_PRODUCTION + "]::", LOGGER);
        String inProduction = "";
        
        try {

            SqlOutParameter isProd = new SqlOutParameter("v_is_prod", OracleTypes.VARCHAR);

            List<SqlParameter> paramList = new ArrayList<SqlParameter>();
            paramList.add(isProd); 
            
            Map<String, Object> resultMap = jdbcTemplate.call(new CallableStatementCreator() {

                public OracleCallableStatement createCallableStatement(Connection connection) throws SQLException {

                    OracleCallableStatement callableStatement = (OracleCallableStatement) connection
                            .prepareCall(IS_RUNNING_IN_PRODUCTION);
                                        
                    callableStatement.registerOutParameter(1, Types.VARCHAR);
                    return callableStatement;
                }
            }, paramList);

            inProduction = (String)resultMap.get("v_is_prod");
                                    
        } catch (Exception e) {
            LOGGER.error("Error while determining if running in prod or not, PROC_NAME::[" + IS_RUNNING_IN_PRODUCTION + "]," + e);
            throw new DaoException("Error while retreiving " + IS_RUNNING_IN_PRODUCTION + e);
        }
        LoggerUtil.info("Finished calling [" + IS_RUNNING_IN_PRODUCTION + "]::", LOGGER);
        
        return inProduction;    
        
    }

Я получаю эту ошибку:

org.springframework.jdbc.InvalidResultSetAccessException: CallableStatementCallback; invalid ResultSet access for SQL []; nested exception is java.sql.SQLException: Invalid column index

По-видимому, registerOutParameter основан на 1, так что callableStatement не является проблемой, первый параметр имеет индекс 1.

Следующий const определен в другом месте:

public static final String IS_RUNNING_IN_PRODUCTION = "FDS_APPS.FDS_USR_SEC_PKG2.is_running_in_production2";

Любые предложения по моей проблеме могут быть?

Попробуйте избавиться от paramList.

OldProgrammer 30.03.2022 19:49

@OldProgrammer спасибо за ответ. paramList является обязательным параметром для jdbc template.call, но, чтобы попытаться следовать вашему предложению, я не добавлял isprod sSqlParameter в paramList и закомментировал оператор registerOutParameter. Я получил ошибку: org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback; плохая грамматика SQL []; вложенным исключением является java.sql.SQLSyntaxErrorException: ORA-00900: неверный оператор SQL. Вы имели в виду что-то еще, кроме того, что я пробовал?

Chad 30.03.2022 20:48
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
2
147
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что вам нужно указать в своем утверждении, что требуется аргумент, например:

public static final String IS_RUNNING_IN_PRODUCTION = "FDS_APPS.FDS_USR_SEC_PKG2.is_running_in_production2(?);";

Обычно оператор завернут в вызов call:

public static final String IS_RUNNING_IN_PRODUCTION = "{call FDS_APPS.FDS_USR_SEC_PKG2.is_running_in_production2(?)}";

Обратите внимание на скобки и символ ?.

В Java и JDBC вам необходимо предоставить заполнитель, используя символ ?, для каждого параметра, требуемого в вашем операторе SQL, независимо от того, является ли он IN или OUT.

Поскольку вы не предоставляете такой заполнитель в своем примере, Spring жалуется, потому что вы пытаетесь зарегистрировать выходной параметр с индексом 1- вы правы, индекс первого столбца 1 -, но для этого параметра нет заполнителя в вашем Оператор SQL.

Пожалуйста, для дальнейших примеров рассмотрите, например, обзор Эта статья, это может помочь.

Я внес изменение и теперь получил эту ошибку: Ошибка при получении FDS_APPS.FDS_USR_SEC_PKG2.is_running_in_production2(?)org.sp‌ringframework.jdbc.B‌​adSqlGrammarExceptio‌​n: CallableStatementCallback; плохая грамматика SQL []; вложенным исключением является java.sql.SQLSyntaxErrorException: ORA-00900: неверный оператор SQL

Chad 01.04.2022 17:02

Большое спасибо за отзыв. Я думаю, проблема в том, что в конце оператора отсутствует точка с запятой, она необходима в Oracle: public static final String IS_RUNNING_IN_PRODUCTION = "FDS_APPS.FDS_USR_SEC_PKG2.is_running_in_production2(?);"; - обратите внимание на конец ; в выражении. Пожалуйста, смотрите обновленный ответ. Пожалуйста, не могли бы вы попробовать еще раз?

jccampanero 01.04.2022 17:04

Бинго! На самом деле мне пришлось удалить точку с запятой после (?), чтобы заставить ее работать, но в основном она у вас была. Пожалуйста, обновите свой ответ, и я с радостью выберу ваш ответ в качестве ответа. приятно иметь с вами дело! Была использована следующая строка: public static final String IS_RUNNING_IN_PRODUCTION = "{call FDS_APPS.FDS_USR_SEC_PKG2.is_running_in_production2(?)}";

Chad 01.04.2022 17:43

Это великолепно. Я очень рад видеть, что ответ был полезен, и, пожалуйста, извините за ошибку: долгое время без использования JDBC; большое спасибо, что указали на мою ошибку. Пожалуйста, не стесняйтесь обращаться ко мне снова, если вам нужна дополнительная помощь

jccampanero 01.04.2022 18:16

если вам интересно, я разместил аналогичный вопрос о том, как изменить код Java, если я изменил процедуру пакета на функцию, а не на процедуру с одним выходным параметром: stackoverflow.com/questions/71757342/…

Chad 05.04.2022 21:25

Извините за задержку с ответом. Конечно, Чад, я рад помочь: я разместил возможное решение вашего нового вопроса. Я надеюсь, что это помогает.

jccampanero 06.04.2022 23:39

Другие вопросы по теме