【问题标题】:Call an Oracle function from Java从 Java 调用 Oracle 函数
【发布时间】:2012-10-20 22:14:49
【问题描述】:

我在使用 ojdbc14.jar 从 Java 1.6 调用 Oracle FUNCTION(不是存储过程)时遇到问题。

当我从远程服务器调用它时,我不知道该函数包含什么,我只知道:

FUNCTION ap_ch_get_acct_balances (VAR_PI_MOB_NO_ACCT_NO VARCHAR2,
VAR_REPLY_CODE OUT NUMBER, VAR_EXT_RESPONSE OUT VARCHAR2, VAR_PO_ACC_BAL OUT CHAR,
VAR_PO_ACCT_NO OUT CHAR)   

我需要使用的架构是:FCRLIVE.AP_CH_GET_ACCT_BALANCES

我正在尝试这个:

String call = "{ ? = call FCRLIVE.AP_CH_GET_ACCT_BALANCES(?, ?, ?, ?, ?) }";
CallableStatement cstmt = conn.prepareCall(call);
cstmt.setQueryTimeout(1800);
cstmt.setString(1, inputCode);
cstmt.registerOutParameter(2, oracle.jdbc.OracleTypes.NUMBER);
cstmt.registerOutParameter(3, oracle.jdbc.OracleTypes.VARCHAR);
cstmt.registerOutParameter(4, oracle.jdbc.OracleTypes.CHAR);
cstmt.registerOutParameter(5, oracle.jdbc.OracleTypes.CHAR);
cstmt.executeUpdate();

但我一直在日志文件中看到这个:

java.sql.SQLException: ORA-01006: bind variable does not exist
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
    at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
    at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:573)
    at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1891)
    at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1093)
    at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2047)
    at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1940)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2688)
    at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:589)

我是否调用了错误的函数?或者这可能是什么?

提前感谢您的帮助!

【问题讨论】:

  • ap_ch_get_acct_balances 的返回类型是什么?
  • 返回4个参数。 3 个整数和 1 个字符串
  • 你的函数应该返回一些东西。 FUNCTION ap_ch_get_acct_balances ( in and out params definition... ) return NUMBER 例如。那么,你的函数返回类型是什么?

标签: java oracle jdbc


【解决方案1】:

实际上有多种方法可以做到这一点。但其中最简单的就是触发查询。 以下是操作方法。

String sql="select myFunction('"+number+"','"+date"') from dual";
statement.execute(sql);

如果您使用的是 JDBC,请设置输入和输出参数。

如果您使用休眠模式,请使用以下命名查询: YourMapping.hbm.xml

<sql-query name="my_function" callable="true">
<return alias="demo" class="net.bean.Demo">
<return-property name="id" column="id"/>
<return-property name="fname" column="fname"/>
<return-property name="lname" column="lname"/>
</return>
    {?=call demoFunc(:param1,:param2)}
</sql-query>

现在这将为函数创建一个命名查询

接下来要做的就是使用以下代码调用它

Query query=session.getNamedQuery("my_function");
query.setParameter("parma1",date);
query.setParameter("parma2",number);
query.executeUpdate();

请注意,在 hbm.xml 文件中存在的返回类名称和属性仅适用于您已映射返回值(如果函数返回适当的值)。

【讨论】:

    【解决方案2】:

    应该是:

    String call = "{ ? = call FCRLIVE.AP_CH_GET_ACCT_BALANCES(?, ?, ?, ?, ?) }";
    

    【讨论】:

    • 感谢您的快速回复!我试过了,然后我得到: java.sql.SQLException: ORA-01008: not all variables bound
    • 那是因为您将绑定设置为仅 5 个参数,而 Oracle 函数中有 6 个:在定义中返回参数 + 5。你也打错了。只有 OUT 参数应该由“registerOutParameter”添加,IN(函数声明中的第一个)参数,作为“setParameter...”)。注意它们的顺序和索引:)
    • 知道了!谢谢!必须再注册一个参数;)
    • 那个链接是怎么回事?
    【解决方案3】:

    您的返回参数只有一个。第一个。那是您必须注册其类型的唯一一个。 所以,第一件事:

    cstmt.registerOutParameter(1, oracle.jdbc.OracleTypes.VARCHAR);

    然后根据需要设置/注册其他参数,但您有 6 个参数,如问号,您只处理 5 个。您还需要设置第 6 个:

    cstmt.setString(6, myVariable);

    如果不清楚,请发布您正在使用的 sql 函数原型,我会指出您确切缺少的绑定。

    【讨论】:

      【解决方案4】:

      你需要定义函数返回的参数:

      String call = "{ ? = call FCRLIVE.AP_CH_GET_ACCT_BALANCES(?, ?, ?, ?, ?) }";
                        CallableStatement cstmt = conn.prepareCall(call);
                        cstmt.setQueryTimeout(1800);
                        cstmt.registerOutParameter(1, ...Type returned by function);
                        cstmt.setString(2, inputCode);
                        cstmt.registerOutParameter(3, oracle.jdbc.OracleTypes.NUMBER);
                        cstmt.registerOutParameter(4, oracle.jdbc.OracleTypes.VARCHAR);
                        cstmt.registerOutParameter(5, oracle.jdbc.OracleTypes.CHAR);
                        cstmt.registerOutParameter(6, oracle.jdbc.OracleTypes.CHAR);
                        cstmt.executeUpdate();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多