Подтвердить что ты не робот

Вызов функции Oracle из Java

У меня возникают проблемы с вызовом Oracle FUNCTION (а не хранимой процедуры) из Java 1.6, используя 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)

Я вызываю функцию неправильно? Или что это может быть?

Заранее благодарим за помощь!

4b9b3361

Ответ 1

это должно быть:

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

Ответ 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();

Ответ 3

ваш возвращаемый параметр - только один. первый. что вы должны зарегистрировать его только один. так что сначала первое:

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

затем установите/зарегистрируйте другие параметры по мере необходимости, но у вас есть 6 параметров, как в вопросительных знаках, и вы обрабатываете только 5. вам также нужно установить 6-й:

cstmt.setString(6, myVariable);

Если это неясно, отправьте прототип используемой функции sql, и я укажу вам на то, что вам не хватает привязки.

Ответ 4

Существует несколько способов сделать это. Но самый простой из них - это запрос. Вот как это сделать.

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

Задайте параметры ввода и вывода, если вы используете JDBC.

Если вы используете hibernate, используйте Named Queries примерно так: 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 имя и свойства класса возврата существуют только в том случае, если вы сопоставили возвращаемые значения, если функция возвращает соответствующие значения.