- PR -

Javaからストアド実行(索引付表のINパラメータの作成)

1
投稿者投稿内容
AkiraNanakase
会議室デビュー日: 2008/04/01
投稿数: 3
投稿日時: 2008-04-01 10:20
初投稿になります。よろしくお願い致します。

現在、Java側から索引付表を引数の型にもつストアドプロシージャ
を呼び出そうとしています。
http://otn.oracle.co.jp/forum/thread.jspa?messageID=11006470
上記サイトを参考に
OUTパラメータの作成の仕方、取得の仕方までは確認しましたが。
索引付表を型に持つINパラメータの作成の仕方が分かりません。

---ストアド----------------------------------------
CREATE OR REPLACE PACKAGE TEST_PAK
IS
TYPE char10_arr IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER;
PROCEDURE TEST_PRO(
TEST_INPARAM IN char10_arr,
TEST_OUTPARAM OUT char10_arr
);
END TEST_PAK;
-----------------------------------------------
---Java----------------------------------------
con = DriverManager.getConnection
("jdbc:oracle:oci:@tns", "xxx", "yyy");
ocs = (OracleCallableStatement)conn.prepareCall("{call
TEST_PAK.TEST_PRO(?,?)}");
// TODO 一つ目のINパラメータの作成の仕方が分かりません
ocs.registerIndexTableOutParameter(2, 10, OracleTypes.VARCHAR, 10);
ocs.execute();
-----------------------------------------------
ここでの配列のINパラメータの作成の仕方で困っています。
別のサイトにArrayDescriptorを使用した作成方法がありましたが、
VARRAYの物しか対応してない?らしく
索引付表の物については上手くいきませんでした。
ArrayDescriptor ad = new ArrayDescriptor("TYPEオブジェクト名", con);
array = new ARRAY(ad, con, {1,2,3});
ocs.setArray( 1, array );

ArrayDescriptorを使用した場合、パッケージの中で
TYPE char10_arr IS TABLE OF VARCHAR2(10) INDEX BY INARY_INTEGER;
と索引付表を宣言していますのでJava側から指定した場合
上手く取得できません。
そこでCREATE TYPE でTYPEオブジェクトを作成しようとしましたが、
CREATE TYPE char10_arr IS TABLE OF VARCHAR2(10) INDEX BY INARY_INTEGER;
PLS-00355: PL/SQL表はこのコンテキストでは使用できません。
とエラーが出まして作成できませんでした。

ストアド部分は提供される物で変更が出来ない為、
Java側で索引付表の物を呼び出さなくてはいけません。
呼び出し方をご教授願えればと思います。よろしくお願いします。
99ri
大ベテラン
会議室デビュー日: 2006/09/09
投稿数: 129
投稿日時: 2008-04-01 20:14
下記参考にしてください
http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/java.102/B19275-03/oraint.htm#i1018084

Oracle Database JDBC開発者ガイドおよびリファレンス
5 Oracle拡張機能
PL/SQL索引付き表へのアクセス
AkiraNanakase
会議室デビュー日: 2008/04/01
投稿数: 3
投稿日時: 2008-04-04 15:12
99riさん、遅くなりましたが返信ありがとうございます!!
参照URLを参考に作成することができました!

簡単なサンプルを載せます

----ストアド--------------------------------------------
CREATE OR REPLACE package eeeee is
TYPE ARR_PART_NUMBER IS TABLE OF VARCHAR2(64) INDEX BY BINARY_INTEGER;
TYPE ARR_PART_NUMBER2 IS TABLE OF NUMBER(38) INDEX BY BINARY_INTEGER;
PROCEDURE SF_TEST_A(
a IN OUT ARR_PART_NUMBER,
b IN OUT ARR_PART_NUMBER2);
end;
--------------------------------------------------------
----java------------------------------------------------
String sql = "{call EEEEE.SF_TEST_A(?,?)}";
OracleCallableStatement cstmt = (OracleCallableStatement) con.prepareCall(sql);

// IN String[]
String[] str = new String[]{"a", "b", "c", "d"};
int strLen = str.length;
cstmt.setPlsqlIndexTable(1, str, strLen, strLen, OracleTypes.VARCHAR, 0);
cstmt.registerIndexTableOutParameter(1, 10, OracleTypes.VARCHAR, 10);

// IN int[]
int[] num = new int[]{3, 2, 1};
int numLen = num.length;
cstmt.setPlsqlIndexTable(2, num, numLen, numLen, OracleTypes.NUMBER, 0);
cstmt.registerIndexTableOutParameter(2, 10, OracleTypes.NUMBER, 10);

cstmt.execute();

String[] out1 = (String[])cstmt.getPlsqlIndexTable (1);
System.out.println(out1.length);
for (int i=0; i<out1.length; i++) {
System.out.println(out1[i]);
}

BigDecimal[] out2 = (BigDecimal[])cstmt.getPlsqlIndexTable (2);
System.out.println(out2.length);
for (int i=0; i<out2.length; i++) {
System.out.println(out2[i]);
}
--------------------------------------------------------
TSUYOSHI
常連さん
会議室デビュー日: 2004/09/02
投稿数: 32
投稿日時: 2008-04-04 17:46
いつも参考にさせていただいております。

私もこの質問と同じことをやろうとして分からないことがありましたので
このスレッドで質問させていただきたいと思います。


AkiraNanakaseさんの質問では、以下の1・2のように要素がVARCHAR2・NUMBERの2種類の型を扱っていましたが
私は、3のようなDATE型で扱いたいと思い同じように作成してみました。

1・・・TYPE ARR_PART_NUMBER IS TABLE OF VARCHAR2(64) INDEX BY BINARY_INTEGER;
2・・・TYPE ARR_PART_NUMBER2 IS TABLE OF NUMBER(38) INDEX BY BINARY_INTEGER;
3・・・TYPE ARR_PART_NUMBER2 IS TABLE OF DATE INDEX BY BINARY_INTEGER;

下記プロシージャソースのPROC03のDATE型を要素にもつTABLEの呼び出しを
「Javaのソース」内にあるtest03メソッドで実行したところ
  st.setPlsqlIndexTable(1, dtmp, 100, dtmp.length, OracleTypes.DATE, 0);
の部分で以下のExceptionが発生しました。

java.sql.SQLException: PL/SQLの索引表の要素タイプが無効です。
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:111)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:145)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:207)
at oracle.jdbc.driver.OraclePreparedStatement.setPlsqlIndexTableInternal(OraclePreparedStatement.java:9664)
at oracle.jdbc.driver.OracleCallableStatement.setPlsqlIndexTable(OracleCallableStatement.java:4743)
at TestDriverServlet.test03(TestDriverServlet.java:647)
at TestDriverServlet.doGet(TestDriverServlet.java:46)
------- 以下、省略 ----------

DATE型だと、なぜうまく呼び出せないのでしょうか?
また、どのような方法であれば呼び出すことができるのでしょうか?

ご教授をお願いいたします。


====== プロシージャのソース =============================================
CREATE OR REPLACE PACKAGE TESTPKG
IS
TYPE tbdt IS TABLE OF DATE INDEX BY BINARY_INTEGER;

PROCEDURE PROC03(
id_data3 IN tbdt,
od_data3 OUT tbdt);

END TESTPKG;
/
CREATE OR REPLACE PACKAGE BODY TESTPKG
IS
PROCEDURE PROC03(
id_data3 IN tbdt,
od_data3 OUT tbdt)
IS
BEGIN
od_data3 := id_data3;
END PROC03;

END TESTPKG;
/

===== Javaのソース ==================================
public void test03() throws Exception
{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@oracledbsv:1521:orcl","test", "test");

OracleCallableStatement st = (OracleCallableStatement)conn.prepareCall("{call TESTPKG.PROC03(?,?)}");

Date[] dtmp = new Date[]{Calendar.getInstance().getTime(),Calendar.getInstance().getTime()};

st.setPlsqlIndexTable(1, dtmp, 100, dtmp.length, OracleTypes.DATE,0); //<-ここでExceptionが発生
st.registerIndexTableOutParameter(2, 100, OracleTypes.DATE, 0);

st.execute();

Object[] rs3 = (Object[])st.getPlsqlIndexTable(2);
System.out.println(rs3[0]+"-"+rs3[1]);
}




AkiraNanakase
会議室デビュー日: 2008/04/01
投稿数: 3
投稿日時: 2008-04-09 10:37
自分も同じようにDATE型での呼び出しを試してみましたが
同じところで落ちてしまいます。
(TIMESTAMPにしても同様)

方法を色々探して見ましたがみつけることが出来ませんでした。
実装されている方、情報が載っているサイトをご存知の方
いらっしゃればよろしくお願いします。
progman
大ベテラン
会議室デビュー日: 2005/06/08
投稿数: 227
投稿日時: 2008-04-09 11:10
99riさんがアップされているURLの表5-3は参考になりませんか?
TSUYOSHI
常連さん
会議室デビュー日: 2004/09/02
投稿数: 32
投稿日時: 2008-04-10 14:33
返答ありがとうございました。

DATE型に関しては、サポートされていないみたいですね。
ありがとうございました。
1

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