从Java调用一个Oracle函数(Call an Oracle function from Jav

2019-07-03 11:51发布

我有从Java调用1.6的Oracle函数(而不是存储过程)问题,使用ojdbc14.jar的。

我不知道该函数包含,因为我从远程服务器调用它,我所知道的是这样的:

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)

我在调用该函数错了吗? 或者什么有这种可能呢?

在此先感谢您的帮助!

Answer 1:

它应该是:

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


Answer 2:

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

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();


Answer 3:

你的回报参数是唯一的一个。 第一个。 这是你必须注册它的类型唯一的一个。 所以,第一件事第一:

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

然后设置/根据需要登记的其他参数,但你有6个参数作为问号,你只处理5,你需要设置一个6号,以及:

cstmt.setString(6,MYVARIABLE);

如果它是不明确的,请发表SQL函数的原型使用的是和我将向您精确缺少约束力。



Answer 4:

其实有这样的多种方式。 但最简单的他们都被解雇的查询。 以下是如何做到这一点。

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

如果你正在使用JDBC设置输入和输出参数。

如果您使用的命名使用Hibernate查询是这样的: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文件中返回的类名,如果你有当函数返回相应的值映射到的返回值的属性只存在适用。



文章来源: Call an Oracle function from Java
标签: java oracle jdbc