2011-08-21 32 views
8

Trong PL/SQL hướng đối tượng, tôi có thể thêm các thủ tục và hàm thành viên vào các kiểu. Một ví dụ được đưa ra ở đây:Gọi thủ tục thành viên PL/SQL hướng đối tượng Oracle từ 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; 

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

Trong PL/SQL, tôi có thể gọi tới các thủ tục thành viên/chức năng như thế này:

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

Làm thế nào tôi có thể làm điều đó với JDBC's CallableStatement? Tôi không thể tìm thấy điều này trong tài liệu một cách dễ dàng.

LƯU Ý: Đây là một khả năng, nội tuyến kiểu constructor:

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

Nhưng những gì tôi đang tìm kiếm là một cái gì đó như thế này (sử dụng java.sql.SQLData như một tham số):

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

Ngoài ra, chức năng thành viên, thủ tục có thể sửa đổi đối tượng. Làm thế nào tôi có thể lấy lại đối tượng đã sửa đổi trong Java?

+0

là cốt lõi của câu hỏi của bạn thực sự "Làm thế nào để gọi một chức năng thành viên"? Hoặc là nó thay vì "Làm thế nào để vượt qua một đối tượng như một tham số"? – Codo

+0

@Codo: Cốt lõi là cách truy xuất các kết quả hàm của thành viên (ví dụ câu trả lời được đưa ra bởi Vincent Malgrat) và cách truy xuất đối tượng có khả năng được sửa đổi chính nó –

Trả lời

4

Trong jdbc bạn có thể phân tích và thực thi các khối PL/SQL với các biến số out. Bạn có thể chuẩn bị một tuyên bố callable như:

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

Sau đó, bạn có thể sử dụng CallableStatement.registerOutParameter và sau khi tuyên bố đã được thực hiện, sử dụng thích hợp get chức năng để lấy giá trị.

Bạn có thể truy cập trực tiếp một loại FOO_TYPE trực tiếp bằng java, nhưng bạn có thực sự muốn làm điều này không? Xem dưới đây cho một ví dụ làm việc:

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/

Đây là một lớp thử nghiệm cho thấy làm thế nào bạn có thể sử dụng phương pháp registerOutParameter vào một đối tượng SQL, chúng ta hãy gọi nó:

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. Tôi không nghĩ rằng thực sự chuyển PL/SQL vào cơ sở dữ liệu, thay vì cú pháp thoát JDBC ... Bạn có bất kỳ ý tưởng nào về cách 'x' chính nó có thể được trả về từ khối PL/SQL không? Trong ví dụ này, 'x' không được sửa đổi bởi các thủ tục/hàm. Nhưng nó có thể được. Vì vậy, khi gọi 'x.func (2)' tôi muốn có cả kết quả hàm như trong ví dụ của bạn * và * giá trị được cập nhật của 'x', như' java.sql.SQLData' ... –

+1

Bạn có thể truy xuất các đối tượng SQL từ PL/SQL trực tiếp vào java STRUCT (ví dụ [ở đây] (http://stackoverflow.com/questions/3626061/how-to-call-oracle-stored-procedure-which-include-user-defined-type -in-java)) Tuy nhiên, tôi luôn thấy nó hơi phức tạp: xem câu trả lời cập nhật của tôi. –

+1

Tuyệt vời! Có, tôi muốn làm điều này. Điều này sẽ được sử dụng chủ yếu trong [thư viện trừu tượng cơ sở dữ liệu] của tôi (http://www.jooq.org). Bạn có thể đã nhìn thấy nó, kể từ khi bạn đã trả lời câu hỏi của tôi trước :-). Mục đích sẽ là tạo một ánh xạ giữa các lớp của UDT và Java. Điều này đã tồn tại, nhưng chỉ cho dữ liệu mà UDT có thể chứa. Việc tạo mã nguồn Java cho các hàm và thủ tục của thành viên thậm chí còn thú vị hơn, vì điều này sẽ làm cho sự tương tác giữa Java và PL/SQL rất dễ dàng đối với mã máy khách, vì chúng không phải gây rối với loại thủ thuật JDBC này. Cảm ơn sự giúp đỡ của bạn. –

Các vấn đề liên quan