java - 使用 Spring StoredProcedure 类调用函数

标签 java spring oracle

我正在尝试使用 Java 和 Spring 调用 Oracle DB 函数。那里有很多例子。此代码库使用 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);
    }
}

这对我不起作用,因为传递给数据库函数的参数不符合我指定的顺序。我尝试过两种不同的方法。使用 Map 调用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

数据库函数确实被调用,但传递的参数是无序的。

最佳答案

我能够弄清楚这一点。显然,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 示例执行相同的操作。

关于java - 使用 Spring StoredProcedure 类调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58087666/

相关文章:

java - 了解 spring 4 (spring-context) maven 依赖

mysql - swingbench 数据生成器连接字符串

java - 如何在 gwt ui-binder 中添加 Canvas ?

Spring Cloud DataFlow 文档缺少部分

java - 按值传递且无返回类型意味着什么也没有发生?

java - 从不同模块加载 Freemarker 模板

java - JPA - EclipseLink - 如何更改默认模式

linux - 数据库未打开错误 ORA-01109

java - Java 11 上的 JFileChooser ,翻译成法语的问题

java - PreparedStatements 的最佳实践;什么时候去,什么时候不去