Oracle PL/SQL Funktion aus Java aufrufen

ThomasMo

Grünschnabel
Ich muß aktuell aus einem Java Programm heraus eine PL/SQL Funktion in einer Datenbank aufrufen. Für einen ersten Test habe ich mir eine Einfache Funktion in der Datenbank (Oracle XE) angelegt:

create or replace package PCK_INTERFACE as

function RECEIVE_EVENTS (EVENTTYPE IN VARCHAR2, EVENTDATE IN DATE, JID IN VARCHAR2, PUFFERID IN VARCHAR2, TRANSPORTERID IN VARCHAR2) return BOOLEAN;

end;

Body:

create or replace package body PCK_INTERFACE is function RECEIVE_EVENTS(EVENTTYPE IN VARCHAR2, EVENTDATE IN DATE, JID IN VARCHAR2, PUFFERID IN VARCHAR2, TRANSPORTERID IN VARCHAR2) return BOOLEAN

as
begin
return false;
end RECEIVE_EVENTS;

end PCK_INTERFACE;

Eigentlich dachte ich, ich könnte diese Funktion über ein SQL-statement "Execute PCK_INTERFACE.RECEIVE_EVENTS(...)" ausführen und den Rückgabewert dann auswerten. Leider bekomme ich jedoch selbst wenn ich das ganze auf der SQL-Kommandozeile der DB-Homepage ausführe ein "ORA-00900: Ungültige SQL-Anweisung" zurück. Hat jemand einen Tip, was ich falsch mache?

Über ein SELECT PCK_INTERFACE.RECEIVE_EVENTS(...) FROM DUAL hatte ich es prinzipiell mal mal Laufen, auch aus Java heraus, allerdings müssen in die DB-Funktion INSERTS, und das kollidiert dann wiederum...
 
Hallo Tom,

danke schon mal, das bringt mich ein Stück weiter!

So läuft das ganze zumindest, wenn ich die PL-Funktion in eine procedure umwandle. Mit Function leider nicht. Gibt es da einen sachlichen Grund, warum das ganze nicht als function läuft?
 
Hallo,

bei einer Oracle Function musst do noch einen entsprechenden OutParameter registrieren:
callableStatement.registerOutParameter(xxxx,xxxxx);

Gruß Tom
 
Hallo,

evtl. stehe ich jetzt etwas auf dem Schlauch. Ich dachte das registerOutParameter verwende ich, wenn ich im Funktionsaufruf OUT-Parameter übergebe. Der OutParameter wäre in meinem Fall dann ja der return-Wert der Funktion Den kann ich ja schlecht benennen oder über einen Parameter-Index ereichen. Oder übersehe ich da was?
 
Als Fehlermeldung bekomme ich:

java.sql.SQLException: ORA-06550: Zeile 1, Spalte 7:
PLS-00221: 'RECEIVE_EVENTS ist keine Prozedur oder ist nicht definiert
ORA-06550: Zeile 1, Spalte 7:
PL/SQL: Statement ignored

Irgendwie hört sich das für mich nicht so an, als würde es am nicht registrierten OutputParameter liegen
 
OK, das SQL-statement noch um ein "? =" am Anfang ergänzt und mit
lo_PreparedStatement.registerOutParameter(6, Types.VARCHAR);
den Output-Parameter gebunden, zumindest Aufrufen kann ich es so. Wenn ich allerdings versuche mir o_PreparedStatement.getString(6); an die Rückgabe zu kommen gibt es nur einen NullPointer zurück :-(
 
Hallo,

hier mal ein Beispiel wie du eine Oracle Function von java aus aufrufen kannst.
SQL:
create or replace function someFunction (value in number, anotherValue in number)
return number
is
begin
return value + anotherValue;
end;

SQL:
SQL> select someFunction(1,2) from dual;

Ausgabe:
Code:
SOMEFUNCTION(1,2)
-----------------
                3



Java:
/**
 * 
 */
package de.tutorials;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Types;

import oracle.jdbc.pool.OracleDataSource;

/**
 * @author Thomas.Darimont
 */
public class CallOracleFunctionViaJDBCExample {

  /**
   * @param args
   */
  public static void main(String[] args) throws Exception {
    OracleDataSource oracleDataSource = new OracleDataSource();
    oracleDataSource.setServerName("xxx");
    oracleDataSource.setPortNumber(1521);
    oracleDataSource.setDatabaseName("xxx");
    oracleDataSource.setUser("xxx");
    oracleDataSource.setPassword("xxx");
    oracleDataSource.setDriverType("thin");

    Connection connection = null;
    try {
      connection = oracleDataSource.getConnection();
      CallableStatement callableStatement = connection.prepareCall("{? = call somefunction(?,?)}");
      callableStatement.registerOutParameter(1, Types.INTEGER);
      callableStatement.setInt(2, 1);
      callableStatement.setInt(3, 2);

      callableStatement.execute();
      System.out.println(callableStatement.getInt(1));

    } finally {
      if (null != connection) {
        connection.close();
      }
    }

  }

}

Gruß Tom
 
Danke nochmal für die Hilfe! Stand gestern wohl etwas auf dem Schlauch und hatte vergessen beim Ändern von procedure auf function die Indizes für den Zugriff auf die Parameter anzupassen :-( Jetzt läuft alles.
 
Hallo

Ich habe auch ein Problem in dem Teil. Ich bekomme immer die Fehlermeldung
Code:
Nicht unterstütztes SQL92-Token in Position: 1:

Mein Code
Code:
CallableStatement callableStatement = con.prepareCall("{@err_num=?,@err_string=?,@err_procedure=? = call create_star_schema(@number=?)}");				
callableStatement.registerOutParameter("@err_num", Types.INTEGER);				
callableStatement.registerOutParameter("@err_string", Types.VARCHAR);
callableStatement.registerOutParameter("@err_procedure", Types.VARCHAR);
callableStatement.setLong("@number", this.getQuelId());					
callableStatement.execute();
callableStatement.getMoreResults();

Kann mir wer sagen wo der Fehler liegt?
 
Zurück