2011-08-21 5 views
8

객체 지향 PL/SQL에서 멤버 프로 시저와 함수를 유형에 추가 할 수 있습니다. 예를 여기에 주어집니다 :JDBC에서 오라클 객체 지향 PL/SQL 멤버 프로 시저 호출

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; 

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

PL/SQL에서, 나는 이들 멤버의 프로 시저를 호출 할 수 있습니다 /이 같은 기능 :

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

내가 함께 할 수있는 방법 JDBC의 CallableStatement? 설명서에서 쉽게 찾을 수없는 것 같습니다.

참고 : 이것은 하나의 가능성이다 유형 생성자 인라인 :

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

하지만 내가 찾는 것은이 같은입니다 (매개 변수로 java.sql.SQLData 사용) :

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

또한 구성원 함수, 프로 시저가 개체를 수정할 수 있습니다. Java에서 수정 된 객체를 다시 얻으려면 어떻게해야합니까?

+0

정말 귀하의 질문의 핵심입니다 "멤버 함수를 호출하는 방법"? 아니면 오히려 "매개 변수로 객체를 전달하는 방법"입니까? – Codo

+0

@Codo : 핵심은 멤버 함수 결과 (Vincent Malgrat가 제공 한 답변 예)를 검색하는 방법과 잠재적으로 수정 된 객체 자체를 검색하는 방법입니다. –

답변

4

jdbc에서 out 변수로 PL/SQL 블록을 구문 분석하고 실행할 수 있습니다.

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

이 그럼 당신은 CallableStatement.registerOutParameter을 사용하고 문이 실행 된 후, 값을 검색하려면 해당 get 기능을 사용할 수 있습니다 : 당신은 같은 호출 명령문을 준비 할 수있다.

직접 FOO_TYPE 유형을 java에 직접 액세스 할 수 있지만 실제로 이것을하고 싶습니까? 작업 예를 들어 아래를 참조하십시오 :

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/

이것은 당신이 SQL 개체의 방법 registerOutParameter을 사용하는 방법을 보여주는 테스트 클래스, 현실을 부르 자 :

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. JDBC escape 구문 대신에 실제로 PL/SQL을 데이터베이스에 전달하는 것을 생각하지 않았습니다 ... PL/SQL 블록에서'x' 자체를 반환하는 방법에 대한 아이디어가 있습니까? 이 예제에서,'x'는 프로 시저/함수에 의해 수정되지 않습니다. 그러나 그것은 있을지도 모른다. 그래서'x.func (2)'를 호출 할 때, 당신의 예제에서와 같은 함수 결과와'x'의 업데이트 된 값을'java.sql.SQLData'처럼 갖고 싶습니다 ... –

+1

당신은 할 수 있습니다. SQL 객체를 PL/SQL에서 java STRUCT로 직접 가져옵니다 (예 [here] (http://stackoverflow.com/questions/3626061/how-to-call-oracle-stored-procedure-which-include-user-defined-type -in-java)) 그러나, 나는 항상 그것이 약간 복잡하다는 것을 안다. 나의 업데이트 된 답변을 보라. –

+1

굉장! 예, 저는 이것을하고 싶습니다. 이것은 주로 [데이터베이스 추상화 라이브러리] (http://www.jooq.org)에서 사용됩니다. 이전에 내 질문에 답변 해봤을 텐데 :-). 목표는 UDT와 Java 클래스 간의 매핑을 만드는 것입니다. 이것은 이미 존재하지만 UDT가 포함 할 수있는 데이터에 대해서만 존재합니다. 멤버 함수와 프로 시저에 대한 Java 소스 코드를 생성하는 것이 훨씬 더 흥미 롭습니다. 이렇게하면 이러한 종류의 JDBC 트릭을 망칠 필요가 없으므로 클라이언트 코드에서 Java와 PL/SQL 간의 상호 작용이 매우 쉬워지기 때문입니다. 도와 주셔서 정말로 고맙습니다. –

관련 문제