2011-08-21 22 views
8

En PL/SQL orientado a objetos, puedo agregar procedimientos y funciones de miembros a tipos. Un ejemplo se da aquí:Llamar a los procedimientos de miembros de PL/SQL orientados a objetos de Oracle desde JDBC

create type foo_type as object (
    foo number, 

    member procedure proc(p in number), 
    member function func(p in number) return number 
); 

create type body foo_type as 
    member procedure proc(p in number) is begin 
    foo := p*2; 
    end proc; 

    member function func(p in number) return number is begin 
    return foo/p; 
    end func; 
end; 

Desde: http://www.adp-gmbh.ch/ora/plsql/oo/member.html

En PL/SQL, entonces me puedo llamar a estos procedimientos miembros/funciones como este:

declare 
    x foo_type; 
begin 
    x := foo_type(5); 
    x.proc(10); 
    dbms_output.put_line(x.func(2)); 
end; 

cómo puedo hacer con ¿CallableStatement de JDBC? Parece que no puedo encontrar esto en la documentación fácilmente.

NOTA: Esta es una de las posibilidades, inlining el tipo constructor:

CallableStatement call = c.prepareCall(
    " { ? = call foo_type(5).func(2) } "); 

Pero lo que estoy buscando es algo como esto (usando java.sql.SQLData como parámetro):

CallableStatement call = c.prepareCall(
    " { ? = call ?.func(2) } "); 

Además, las funciones miembro, los procedimientos pueden modificar el objeto. ¿Cómo puedo recuperar el objeto modificado en Java?

+0

es el núcleo de su pregunta realmente "¿Cómo llamar a una función de miembro"? ¿O es más bien "Cómo pasar un objeto como parámetro"? – Codo

+0

@Codo: El núcleo es cómo recuperar los resultados de la función miembro (ejemplo de respuesta dada por Vincent Malgrat), y cómo recuperar el objeto potencialmente modificado –

Respuesta

4

En jdbc puede analizar y ejecutar bloques PL/SQL con variables out. Se podría preparar una declaración exigible tales como:

declare 
    x foo_type; 
begin 
    x := foo_type(5); 
    x.proc(10); 
    ? := x.func(2); 
end; 

continuación, puede utilizar CallableStatement.registerOutParameter y después de la declaración ha sido ejecutado, utilice la función apropiada get para recuperar el valor.

Puede acceder directamente a un tipo FOO_TYPE directamente en java, pero ¿realmente desea hacer esto? A continuación encontrará un ejemplo de trabajo:

SQL> create or replace and compile java source named "TestOutParam" as 
    2 import java.sql.*; 
    3 import oracle.sql.*; 
    4 import oracle.jdbc.driver.*; 
    5 
    6 public class TestOutParam { 
    7 
    8  public static int get() throws SQLException { 
    9 
10  Connection conn = 
11   new OracleDriver().defaultConnection(); 
12 
13  StructDescriptor itemDescriptor = 
14   StructDescriptor.createDescriptor("FOO_TYPE",conn); 
15 
16  OracleCallableStatement call = 
17   (OracleCallableStatement) conn.prepareCall("declare\n" 
18    + " x foo_type;\n" 
19    + "begin\n" 
20    + " x := foo_type(5);\n" 
21    + " x.proc(10);\n" 
22    + " ? := x;\n" 
23    + "end;\n"); 
24 
25  call.registerOutParameter(1, OracleTypes.STRUCT, "FOO_TYPE"); 
26 
27  call.execute(); 
28 
29  STRUCT myObj = call.getSTRUCT(1); 
30 
31  Datum[] myData = myObj.getOracleAttributes(); 
32 
33  return myData[0].intValue(); 
34 
35  } 
36 } 
37/

Esta es una clase de prueba para mostrar cómo se puede utilizar el método registerOutParameter en un objeto SQL, vamos a llamarlo:

SQL> CREATE OR REPLACE 
    2 FUNCTION show_TestOutParam RETURN NUMBER 
    3 AS LANGUAGE JAVA 
    4 NAME 'TestOutParam.get() return java.lang.int'; 
    5/

Function created 

SQL> select show_testoutparam from dual; 

SHOW_TESTOUTPARAM 
----------------- 
       20 
+1

Duh. No pensé en pasar PL/SQL a la base de datos, en lugar de la sintaxis de escape de JDBC ... ¿Tiene alguna idea sobre cómo se podría devolver 'x' en sí mismo desde el bloque PL/SQL? En este ejemplo, 'x' no es modificado por los procedimientos/funciones. Pero puede ser. Entonces cuando llamo 'x.func (2)' Me gustaría tener el resultado de la función como en su ejemplo * y * el valor actualizado de 'x', como' java.sql.SQLData' ... –

+1

Puede recuperar objetos SQL de PL/SQL directamente en java STRUCT (ejemplo [aquí] (http://stackoverflow.com/questions/3626061/how-to-call-oracle-stored-procedure-which-include-user-defined-type -in-java)) Sin embargo, siempre me parece un poco intrincado: ver mi respuesta actualizada. –

+1

¡Impresionante! Sí, quiero hacer esto. Esto se usará principalmente en mi [biblioteca de abstracción de bases de datos] (http://www.jooq.org). Es posible que lo haya visto, ya que ha respondido a mis preguntas antes :-). El objetivo será crear una asignación entre las clases de UDT y Java. Esto ya existe, pero solo para los datos que un UDT puede contener. Generar código fuente Java para funciones y procedimientos de miembros es aún más interesante, ya que esto hará que las interacciones entre Java y PL/SQL sean muy fáciles para el código del cliente, ya que no tienen que meterse con este tipo de trucos de JDBC. Muchas gracias por tu ayuda. –

Cuestiones relacionadas