2012-10-31 20 views
12

Ho problemi a chiamare Oracle FUNCTION (non una stored procedure) da Java 1.6, utilizzando ojdbc14.jar.Chiama una funzione Oracle da Java

Non so quale sia la funzione contiene come mi chiamo da un server remoto, tutto quello che so è questo:

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) 

Lo schema che ho bisogno di usare è: FCRLIVE.AP_CH_GET_ACCT_BALANCES

sto cercando in questo modo:

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

Ma io continuo a vedere questo nel file di registro:

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) 

Sto chiamando la funzione errata? O cosa potrebbe essere?

Grazie in anticipo per l'aiuto!

+0

quale tipo di ritorno di "ap_ch_get_acct_balances'? – user1516873

+0

Restituisce 4 parametri. 3 numeri interi e 1 stringa – lulu88

+1

La tua funzione dovrebbe restituire qualcosa. 'FUNZIONE ap_ch_get_acct_balances (definizione dei parametri in entrata e in uscita ...) restituisce NUMBER' per esempio. Quindi, quale funzione restituisce la funzione? – user1516873

risposta

10

dovrebbe essere:

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

Grazie per la rapida risposta! L'ho provato, quindi ho ricevuto: java.sql.SQLException: ORA-01008: non tutte le variabili rilevano – lulu88

+0

perché si imposta il binding a soli 5 parametri e si dispone di 6 in funzione Oracle: restituisce param + 5 nella definizione. Inoltre hai sbagliato a digitare. Solo i parametri OUT devono essere aggiunti dai parametri "registerOutParameter" e IN (first in function declaration), come "setParameter ..."). Fai attenzione al loro ordine e agli indici :) – konradkg

+0

L'ho visto! Ora ho cambiato il codice - modificato sopra .. – lulu88

0

è necessario definire il parametro restituito dalla funzione:

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

tuo parametro di ritorno è solo uno. il primo. questo è l'unico che devi registrare il suo tipo. così, la prima cosa prima:

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

quindi impostare/registrare gli altri parametri in base alle esigenze, ma si dispone di 6 parametri come in punti interrogativi e di gestire solo 5. è necessario impostare il 6 ° uno pure:

cstmt .setString (6, myVariable);

se non è chiaro, si prega di inviare il prototipo della funzione sql che si sta utilizzando e indicherò il binding mancante.

-1

Esistono diversi modi per farlo. Ma il più semplice di tutti è sparare una query. Ecco come farlo.

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

Impostare i parametri di input e output se si utilizza JDBC.

Se si utilizza l'uso di ibernazione Named Query qualcosa di simile: 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> 

Ora, questo creerà una query denominata per la funzione

prossima cosa da fare è chiamalo semplicemente usando il seguente codice

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

Nota che in hbm.file xml il nome della classe restituita e le proprietà esistenti si applicano solo se sono stati mappati i valori restituiti se la funzione restituisce valori appropriati.