# Java und Oracle Funktion



## Paata (17. Okt 2004)

Ich habe folgende Funktion in Oracle:


```
create or replace function sf_SearchStudent(
       nID in  number
       ) 
return MyPackage.CursorType is
Result MyPackage.CursorType;
begin
  open Result for select * from STUDENT where ID=nID;
  return Result;
end sf_SearchStudent;
```

Das arbeiten in Oracle Fein, aber  wenn ich ruffe Function (oben geschriebene Code) von Java:


```
CallableStatement callst = conn.prepareCall("{?=call sf_SearchStudent(?,?,?,?)}");                                            
      callst.registerOutParameter(1, OracleTypes.CURSOR);
      callst.setInt(1,id);
      callst.setString(2,name);
      callst.setString(3,surname);
      callst.setInt(4,age);
      callst.executeUpdate();   ------->>>>> ERROR Occur

      ResultSet res = ((OracleCallableStatement)callst).getCursor(4);
      while (res.next())
      {
       System.out.println(res.getInt("ID"));
       System.out.println(res.getString("NAME"));
       System.out.println(res.getString("SURNAME"));
       System.out.println(res.getInt("AGE"));
     }
```

dann habe ich eine Probleme, etwas ist falsch... bitte, helfen!


----------



## foobar (17. Okt 2004)

> dann habe ich eine Probleme, etwas ist falsch... bitte, helfen!


Was kriegst du denn für eine Exception? Poste doch mal den Stacktrace.


----------



## Bleiglanz (18. Okt 2004)

willst du uns veralbern?

du hast nur einen Parameter (nId), wieso versuchst du, der storedProc vier Parameter zu übergeben??


----------



## Guest (18. Okt 2004)

Ja Sie haben Recht, diese 4 parameter  ist einfach mechanische falsch und das ist nichr meine konkrette  Problem. 
Eine code:

CallableStatement callst = conn.prepareCall("{?=call sf_SearchStudent(?,?,?,?)}");                                            
callst.registerOutParameter(1, OracleTypes.CURSOR); 
callst.setInt(1,id); 
callst.executeUpdate();   ------->>>>> *ERROR* ----HIER IST PROBLEM---------------------<<<<<<<<<
ResultSet res = ((OracleCallableStatement)callst).getCursor(4); 
while (res.next()) 
{ 
  System.out.println(res.getInt("ID")); 
  System.out.println(res.getString("NAME")); 
  System.out.println(res.getString("SURNAME")); 
  System.out.println(res.getInt("AGE")); 
} 

Java gibt mir folgende ERROR:

java.sql.SQLException: Missing IN or OUT parameter at index:: 1


----------



## Bleiglanz (18. Okt 2004)

dann müssen aber auch die 4 Fragezeichen weg (weils ja nur ein out-Parameter ist = das resultset und ein eingabeparameter nid)

```
CallableStatement callst = conn.prepareCall("{?=call sf_SearchStudent(?)}"); 
callst.registerOutParameter(1, OracleTypes.CURSOR);
callst.setInt(2,id); 
callst.executeUpdate(); 
ResultSet res = ((OracleCallableStatement)callst).getCursor(1);
```


----------



## paata (18. Okt 2004)

Danke fuer deine Raten, aber das ist auch nicht ein Fehler, ich habe alle varianten probiert, aber trotzdem Java zeigt mir dieselbe ERROR:

java.sql.SQLException: Missing IN or OUT parameter at index:: 2

Eine Code in Java habe ich so geschrieben:

CallableStatement callst = conn.prepareCall("{?=call sf_SearchStudent(?)}"); 
callst.registerOutParameter(1, OracleTypes.CURSOR); 
callst.setInt(2,id); 
callst.executeUpdate();   ---------->>>>>>>>> ERROR --------------<<<<<<<<<<<<<<<<<
ResultSet res = ((OracleCallableStatement)callst).getCursor(1);


----------



## abollm (18. Okt 2004)

paata hat gesagt.:
			
		

> Danke fuer deine Raten, aber das ist auch nicht ein Fehler, ich habe alle varianten probiert, aber trotzdem Java zeigt mir dieselbe ERROR:
> 
> java.sql.SQLException: Missing IN or OUT parameter at index:: 2
> 
> ...



Ist die Oracle-Funktion innerhalb eines Packages?


----------



## Bleiglanz (18. Okt 2004)

```
conn.prepareCall("{?=call sf_SearchStudent(?)}");
```
stimmt wohl nicht weil ein Doppelpunkt fehlt; entweder "native"

```
conn.prepareCall("begin ? := sf_SearchStudent(?); end;");
```
oder mit "jdbc"-Syntax

```
conn.prepareCall("{ call ? := sf_SearchStudent((?) }");
```


----------



## abollm (14. Nov 2004)

Paata hat gesagt.:
			
		

> Ich habe folgende Funktion in Oracle:
> 
> ...
> 
> ...



Diese Aussage ist leider falsch, da ich die o.a. Funktion so nicht zum Laufen gebracht habe.

Außerdem sollte man - außer in reinen Demos - Stand-Alone-Funktionen in 
Oracle-Produktivumgebungen _grundsätzlich_ vermeiden. 
Deshalb habe ich ein Package mit der Funktion angelegt.

Der Aufruf aus Java sieht dann wie folgt aus:

```
/*
 * Created on 14.11.2004
 *
 * @author ABollm
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 *
 *
 * Dieses Beispiel zeigt den Aufruf von PL/SQL-Objekten via JDBC.
 */

import java.sql.*;
import oracle.jdbc.driver.*;

class PCKCallStudent
{
  public static void main (String args [])
       throws SQLException, ClassNotFoundException
  {

    // Laden des Oracle JDBC Treibers (hier OCI, s.u.)
    DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());

    String url = "jdbc:oracle:oci8:@..."; // SID etc. eintragen
     try {
      String url1 = System.getProperty("JDBC_URL");
      if (url1 != null) {
        url = url1;
      }
      System.out.println ("URL: " + url+"\n");
    } catch (Exception e) {
      // Falls irgendeine (Sicherheits-) Ausnahme auftritt, ignorieren
      // Standard ...
    }

    // Verbindung zur Datenbank
    Connection conn =
      DriverManager.getConnection (url, "scott", "tiger");

    // Aufruf einer SP mit IN und OUT Parameter
    //String query = "begin :1 := sp_listEmp; end;";

    // PL/SQL-Aufruf vorbereiten
    CallableStatement call =
       conn.prepareCall ("{ ? = call pck_student.sf_searchstudent (?)}");

    // bestimmten Studenten-Datensatz heraussuchen
    call.registerOutParameter (1, OracleTypes.CURSOR);
    call.setInt(2,7369);                                // hier die Datensatz-ID einfügen!

    call.execute ();
    ResultSet rset = (ResultSet)call.getObject (1);

    // Cursor mit kompl. Datensatz ausgeben
    while (rset.next ()) {
       System.out.println ("Name:        "+rset.getString ("NAME"));
       System.out.println ("Surname:     "+rset.getString ("SURNAME"));
       System.out.println ("Age (years): "+rset.getString ("AGE"));
       System.out.println ("Imm. Date:   "+rset.getString ("IMMATRICULATIONDATE"));
       //...
    }
    // Alles schließen
    rset.close();
    call.close();
    conn.close();
  }
}
```
Falls Interesse an den SQL-Statements zum Anlegen der Tabelle und des Packages besteht, bitte
hier kurz eine Nachricht posten. Ich werde den Code dann ebenfalls einstellen.


----------

