lulu88
lulu88

Reputation: 1714

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!

Upvotes: 23

Views: 59936

Answers (4)

Darshan Lila
Darshan Lila

Reputation: 5868

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.

Upvotes: -1

konradkg
konradkg

Reputation: 691

it should be:

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

Upvotes: 23

user2099642
user2099642

Reputation: 1

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.

Upvotes: 0

user2354452
user2354452

Reputation: 31

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

Upvotes: 3

Related Questions