简体   繁体   中英

Call an Oracle function from Java

I am having issues calling an Oracle FUNCTION (not a Stored Procedure) from Java 1.6, using ojdbc14.jar.

I do not know what the function contains as I am calling it from a remote server, all I know is this:

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)   

The schema I need to use is: FCRLIVE.AP_CH_GET_ACCT_BALANCES

I am trying this:

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

But I keep seeing this in the log file:

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)

Am I calling the function wrong? Or what could this possibly be?

Thanks in advance for the help!

它应该是:

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

You need to define parameter returned by function:

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

your return parameter is only one. the first one. that's the only one you must register its type. so, first thing first:

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

then set/register the other parameters as needed, but you have 6 parameters as in question marks and you handle only 5. you'll need to set the 6th one as well:

cstmt.setString(6, myVariable);

if it is not clear, please post the prototype of sql function you are using and I'll point you to exact missing binding.

There are actually multiple ways of doing so. But the easiest of them all is firing a query. Here's how to do it.

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

Set the input and output parameters if you are using JDBC.

If you are using hibernate use Named Queries something like this: 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>

Now this will create a Named Query for the function

Next thing to do is simply call it using following code

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

Note that in hbm.xml file the return class name and properties exists only apply if you have mapped the returning values if the function returning appropriate values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM