- PR -

Javaからストアドファンクションを実行し、oracleコレクションをキャストする方法

1
投稿者投稿内容
未記入
会議室デビュー日: 2008/07/17
投稿数: 3
投稿日時: 2008-07-17 15:52
JavaからOracleCallableStatementを使って、
ストアドファンクションを実行し、コレクションを返したいのですが、
Java側でのキャストに問題があるのかうまくいきません。
コレクションのキャストの仕方についてアドバイスいただけませんでしょうか。



以下にソースを貼り付けます。
PL/SQL(プロシージャ自体の実行は問題ありませんでした)

------------------------------------------------------------
■タイプ作成
CREATE TYPE DATA_T IS VARRAY (100) OF varchar2(1000)
/
CREATE TYPE ARRAY_T IS VARRAY (100) OF DATA_T;
/

■パッケージ
create or replace package sampleSQL as
function getMultipleArray(param1 in varchar2,param2 in varchar2)
return array_t ;
end sampleSQL;
/

create or replace package body sampleSQL as

function getMultipleArray(param1 in varchar2,param2 in varchar2)
return array_t is

begin
declare
l_2d_grid array_t := array_t();

column_num number := 3;
row_num number := 3;

begin

--初期化
l_2d_grid.EXTEND(row_num);

for loop1 in 1..row_num loop
l_2d_grid(loop1) := data_t();
l_2d_grid(loop1).EXTEND(column_num);
end loop;

--set
for loop1 in 1..row_num loop
for loop2 in 1..column_num loop
l_2d_grid(loop1)(loop2) := param1 ||':'||loop1||':'|| param2 ||loop2;
end loop;
end loop;

return l_2d_grid;

end;
end getMultipleArray;


end sampleSQL;
/


------------------------------------------------------------
■Java
------------------------------------------------------------


import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Struct;
import java.sql.Types;

import oracle.jdbc.*;
import oracle.sql.*;



public class sampleClass {

public static void main(String[] args) throws SQLException {

try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
return;
}

Connection conn = null;
try {
conn = DriverManager.getConnection("jdbc:oracle:oci8:@aaa",
"user",
"pass");
} catch (SQLException e) {
e.printStackTrace();
return;
}

System.out.println("connection success");

try {

CallableStatement stmt = conn.prepareCall("{? = call sampleSQL.getMultipleArray(?, ?)}");
stmt.registerOutParameter(1,Types.ARRAY,"ARRAY_T");
stmt.setString(2, "A");
stmt.setString(3, "B");

stmt.execute();

Array array = stmt.getArray(1);
//ここでエラー
String[] values = (String[])array.getArray();
for( int i = 0; i < values.length; i++ )
System.out.println( "row " + i + " = '" + values[i] +"'" );

stmt .close ();
conn.close ();

} catch (SQLException e) {
e.printStackTrace();
}
}

}


---------------------------------------------------------
console

connection success
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object;
at sampleClass.main(sampleClass.java:51)

かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2008-07-17 16:59
引用:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object;
at sampleClass.main(sampleClass.java:51)


Object型の配列をString型の配列にキャストしようとして、失敗している例外ですね。
Object型の配列の中身がStringのインスタンスの可能性もありますが、
ひとまずはObject型配列へのキャスト、各要素の型のチェックを行ってみてください。
未記入
会議室デビュー日: 2008/07/17
投稿数: 3
投稿日時: 2008-07-22 12:32
返信遅くなりました。
レスありがとうございます。

Object型配列へのキャストはうまくいきました。
もうひとつ質問なのですが、
Object型配列を出力するにはどうしたらいいのでしょうか。
初心者な質問で申し訳ありませんが、
アドバイスいただけませんか。

Object[] structs = (Object[]) array.getArray();

//structsを出力したいが、記述の仕方が分からない・・・
for( int i = 0; i < structs.length; i++ ) {
System.out.println(((oracle.sql.ARRAY) structs[i]).getClass().getFields());
}

よろしくお願いします。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2008-07-22 13:55
何がどうわからないのでしょうか?
エラーになっているのでしょうか?

単純にstructs[i]を出力するだけじゃダメなんですか?
何をどういう目的でどのように出力したいのかわからないので、
具体的なアドバイスでできません。
未記入
会議室デビュー日: 2008/07/17
投稿数: 3
投稿日時: 2008-07-22 14:21
すみません。
説明不足でした。
下記のPLSQLから実行した結果のように
Javaコンソールに出力できればいいだけです。

l_2d_grid(1)(1)=A:1:B1
l_2d_grid(1)(2)=A:1:B2
l_2d_grid(1)(3)=A:1:B3
l_2d_grid(2)(1)=A:2:B1
l_2d_grid(2)(2)=A:2:B2
l_2d_grid(2)(3)=A:2:B3
l_2d_grid(3)(1)=A:3:B1
l_2d_grid(3)(2)=A:3:B2
l_2d_grid(3)(3)=A:3:B3

PLSQLから実行したスクリプト---------------------------
begin
declare

l_2d_grid array_t := array_t();

begin

sampleSQL.getMultipleArray('A','B',l_2d_grid);

for loop0 in 1..l_2d_grid.count loop
for loop1 in 1..l_2d_grid(1).count loop
dbms_output.put_line('l_2d_grid('|| loop0 ||')('|| loop1 ||')='||l_2d_grid(loop0)(loop1));
end loop;
end loop;

end;
end;
/
-----------------------------------------------------------------------

これをJavaでどのように書けばいいのか、
調べていても分かりませんでした。

よろしくお願いします。

かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2008-07-22 15:17
今手元にOracleがないので、ヒントだけ。

structs[i]とstructs[i].getClass()を出力してみてください。
structs[i]はキャストされたObject配列の要素の文字列表現、
structs[i].getClass()はそのオブジェクトの実クラスです。

各配列の要素を、その実クラスもしくは親クラス等にキャストしてやれば、
お目当ての出力に使える値の取得が可能なメソッドが出てくるかもしれません。
1

スキルアップ/キャリアアップ(JOB@IT)