Использование класса Spring StoredProcedure для вызова функции - PullRequest
1 голос
/ 24 сентября 2019

Я пытаюсь вызвать функцию БД Oracle, используя Java и Spring.Есть много примеров там.Эта кодовая база использует Spring версии 4.2.13.RELEASE.Вот мой код:

    public void someMethod(Long oldUserId, Long newUserId, String loginId, Long profileId) throws Exception
   {
    class MyFunction extends StoredProcedure
    {
        public MyFunction (DataSource ds)
        {
            setDataSource(ds);
            setFunction(true);
            setSql("myschema.f_m_user");
            // this function takes 4 input arguments and returns 1 output parameter.
            declareParameter(new SqlParameter("par_login_id", Types.VARCHAR));
            declareParameter(new SqlParameter("par_old_user_id", Types.NUMERIC));
            declareParameter(new SqlParameter("par_new_user_id", Types.NUMERIC));
            declareParameter(new SqlParameter("par_user_profile_id", Types.NUMERIC));
            declareParameter(new SqlOutParameter("returnValue", Types.VARCHAR)); 
            compile();
        }

        public String execute(String parLoginId, Long parCurUserId, Long parNewUserId, Long parProfileId)
        {
            //Map inParams = new HashMap();
            //inParams.put("par_login_id", parLoginId);
            //inParams.put("par_old_user_id", parCurUserId);
            //inParams.put("par_new_user_id", parNewUserId);
            //inParams.put("par_user_profile_id", parProfileId);
            //Map result = execute(inParams);
            Map result = super.execute(parLoginId, parCurUserId, parNewUserId, parProfileId);
            String errorMsg = null;
            if (!result.isEmpty() && result.get("returnValue") != null)
            {
                errorMsg = result.get("returnValue").toString();
            }
            return errorMsg;
        }
    } // end class

    MyFunction func = new MyFunction (ds);
    String errorMsg = func.execute(
        loginId,
        oldUserId,
        newUserId,
        profileId);
    if (errorMsg != null)
    {
        throw new Exception(errorMsg);
    }
}

Это не работает для меня, потому что параметры, передаваемые в функцию DB, не в указанном мной порядке.Я пробовал это 2 разными способами.Вызов execute с картой и вызов execute (см. Код) с переменным числом аргументов.Удивительно, но оба метода для меня неудачны.Я чувствую, что упускаю что-то простое, или у стороны Oracle есть проблема с объявлением функции.Ниже приведена подпись для функции Oracle:

CREATE OR REPLACE FUNCTION myschema.f_m_user
-- Returns the oracle error message
(
par_login_id        IN profile.login_id%TYPE,
par_old_user_id     IN profile.user_id%TYPE,
par_new_user_id     IN profile.user_id%TYPE,
par_user_profile_id     IN profile.mod_profile_id%TYPE
)

RETURN VARCHAR2

IS

BEGIN … more code not shown

Функция БД действительно вызывается, но переданные аргументы не в порядке.

1 Ответ

0 голосов
/ 25 сентября 2019

Я смог понять это.По-видимому, важен порядок операторов DeclareParameter (…).Я предполагаю, что пропустил эту информацию в документах.Исправленный код:

        declareParameter(new SqlOutParameter("returnValue", Types.VARCHAR)); 
        declareParameter(new SqlParameter("par_login_id", Types.VARCHAR));
        declareParameter(new SqlParameter("par_old_user_id", Types.NUMERIC));
        declareParameter(new SqlParameter("par_new_user_id", Types.NUMERIC));
        declareParameter(new SqlParameter("par_user_profile_id", Types.NUMERIC));
        compile();

Я переместил оператор returnValue перед параметрами in.Я смог понять это, построив другой пример, но с использованием prepareCall, который выглядит следующим образом:

stmt = conn.prepareCall("{? = call utility.f_m_user(?,?,?,?) }");

Это сработало.Так как возвращаемое значение указывается здесь первым, это был хороший совет, мне нужно было сделать то же самое для примера Spring StoredProcedure.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...