2017-01-23 4 views
-2

javaストアド・プロシージャにoracleオブジェクト型を渡すことは可能です。ここに私がこれまで持っていたものがあります。javaストアド・プロシージャへのoracleオブジェクト型の受け渡し

Javaストアド・プロシージャ:

create or replace and compile java source named Example as 
import java.sql.SQLData; 
import java.sql.SQLException; 
import java.sql.SQLInput; 
import java.sql.SQLOutput; 

public class Example { 

    public static void test(ExObj obj) { 
     System.out.println(obj.client); 
    } 

    public static class ExObj implements SQLData { 

     public String client = ""; 

     public String sql_type = "EXAMPLE_OBJECT"; 

     public ExObj(String client, String sql_type) { 
      this.client = client; 

      this.sql_type = sql_type; 
     } 

     /* IMPLEMENTS SQLData */ 

     public void setSqlType(String sqlType) { 
      sql_type = sqlType; 
     } 

     public void writeSQL(SQLOutput stream) throws SQLException { 
      stream.writeString(this.client); 
     } 

     public String getSQLTypeName() { 
      return sql_type; 
     } 

     public void readSQL(SQLInput stream, String sqlTypeName) throws SQLException { 
      sql_type = sqlTypeName; 

      this.client = stream.readString(); 
     } 

    } 
} 

Oracleプロシージャ:

CREATE OR REPLACE PROCEDURE example(ex_obj in example_object) 
AS LANGUAGE JAVA 
NAME 'Example.test(java.sql.Struct)'; 

Oracleオブジェクト型:

create or replace type example_object as object(
    client varchar2(40) 
) 

スクリプトを呼び出すための手順:

declare 
    l_output DBMS_OUTPUT.chararr; 
    l_lines INTEGER := 1000; 

    l_obj example_object; 
begin 
    DBMS_OUTPUT.enable(1000000); 
    DBMS_JAVA.set_output(1000000); 

    l_obj := example_object('client'); 
    example(l_obj); 

    DBMS_OUTPUT.get_lines(l_output, l_lines); 

    FOR i IN 1 .. l_lines LOOP 
    -- Do something with the line. 
    -- Data in the collection - l_output(i) 
    DBMS_OUTPUT.put_line(l_output(i)); 
    END LOOP; 
end; 

スクリプトを実行しているとき、私は取得しない:

ORA-29531:クラスの例にはメソッドのテストを

ORA-06512: "例" の行1

ORA-06512:行で17

oracle object_typeがJavaクラスに正しくマップされないためです。これを行う方法はありますか、もしそうなら、何が間違っていますか?

+1

があなたの 'ExObj'のコンストラクタは、実際に、二つの引数を持っているべきですか? 'sqlType'をコンストラクタに渡しているのはなぜですか?定数であるべきですか? –

+0

はい、JavaクラスをOracleオブジェクト型にマップする必要があります。それは私がJavaクラスをOracleに返すときに機能します。 public static ExObj test1(String str){新しいExObj(str)を返します};だから私はオブジェクト型をjavaに渡すときにも動作するはずです。 –

答えて

1

あなたのコードで以下に述べる問題が原因である可能性があります。

1)objecttypeという名前の宣言が必要です。 objectdatatypeとして直接使用することはできません。以下を参照してください:

デモ:SQLオブジェクトは一つだけfieildを持っている場合

create or replace type example_object as object(
    client varchar2(40) 
); 

/

--Created a type of the object 
create or replace type x is table of example_object; 

/


CREATE OR REPLACE PROCEDURE example(ex_obj in X) 
    AS 
    begin 

    DBMS_OUTPUT.put_line('Example.test(java.sql.Struct'); 
    DBMS_OUTPUT.put_line('Inside the Procedure'); 
    DBMS_OUTPUT.put_line (ex_obj(1).client); 

    end; 
/

    DECLARE 
     l_output DBMS_OUTPUT.chararr; 
     l_lines INTEGER := 1000; 

     l_obj  x := x();  

    BEGIN 
     DBMS_OUTPUT.enable (1000000); 
     --DBMS_JAVA.set_output (1000000); 

     --You need to mention the position where the record will be saved in table. 
     l_obj.extend(); 
     l_obj(1) := example_object('client1'); 

     example (l_obj); 

     DBMS_OUTPUT.put_line (l_obj(1).client); 

     DBMS_OUTPUT.get_lines (l_output, l_lines); 

     FOR i IN 1 .. l_lines 
     LOOP 
      -- Do something with the line. 
      -- Data in the collection - l_output(i) 
      DBMS_OUTPUT.put_line (l_output (i)); 
     END LOOP; 
    END; 

/

+0

私はストアドプロシージャに配列を渡すことしかできないと言っていますか? –

+1

いいえ。私はあなたのオブジェクトの種類を最初に作成し、それをデータ型として使用する必要があると言っています。私はあなたのオブジェクトのタイプを連想配列として作成し、それを使用しました。私はそれを入れ子にしたテーブルとしても使うことができますが、それは私のためにコードで行うべき追加のことをもたらします – XING

+0

私はJavaストアドプロシージャを呼び出すプロシージャを変更する必要がどのように例を使って答えを更新できますか?私はjavaの引数としてjava.sql.Arrayを使用する必要がありますか? –

関連する問題