我在使用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)
我是否错误地调用了该函数?或者这可能是什么?
提前感谢您的帮助!
答案 0 :(得分:15)
它应该是:
String call = "{ ? = call FCRLIVE.AP_CH_GET_ACCT_BALANCES(?, ?, ?, ?, ?) }";
答案 1 :(得分:1)
您需要定义函数返回的参数:
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();
答案 2 :(得分:0)
你的返回参数只有一个。第一个。这是你必须注册其类型的唯一一个。 所以,首先要做的事情是:
cstmt.registerOutParameter(1,oracle.jdbc.OracleTypes.VARCHAR);
然后根据需要设置/注册其他参数,但你有6个参数作为问号而你只处理5.你还需要设置第6个参数:
cstmt.setString(6,myVariable);
如果不清楚,请发布你正在使用的sql函数的原型,我会指出你完全没有绑定。
答案 3 :(得分:-1)
实际上有多种方法可以做到这一点。但其中最简单的就是触发查询。 这是怎么做的。
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文件中,只有在函数返回适当值时映射了返回值,才会应用返回类名和属性。