2016-06-11 12 views
1

に連想配列を返すために、私はJavaへの連想配列を返すようにしようとしますが、例外に直面しています。私は、独自の永続化層を使用していますので、私は私のコードを投稿することができませんが、Googleで検索しながら、私は私が持っているものとまったく似て何かを発見した:PLSQL - どのようにJavaの

=========== ================

create or replace PACKAGE testLookAside as 
type AssocArry IS TABLE OF varchar(30) INDEX BY VARCHAR(30); 
function lookupMasterData return AssocArry; 
end testLookAside; 
/
create or replace PACKAGE BODY testLookAside as 
function lookupMasterData_ return AssocArry as 
retval AssocArry; 
begin 
retval('1') := '1'; 
retval('2') := '2'; 
retval('3') := '3'; 
retval('4') := '4'; 
return retval; 
end lookupMasterData_; 
/
function lookupMasterData return AssocArry as 
retVal AssocArry; 
begin 
retVal := lookupMasterData_(); 
return retVal; 
end lookupMasterData; 
end testLookAside; 

Statement s = null;; 
Class.forName("oracle.jdbc.driver.OracleDriver"); 
// set up connection here.... 
s=con.createStatement(); 

//String query = "begin ? := DEVELOPER.testLookAside.lookupMasterData(); end;"; 
String query = "{? = call DEVELOPER.testLookAside.lookupMasterData()}"; 

OracleCallableStatement stmt = (OracleCallableStatement)con.prepareCall(query); 

// register the type of the out param - an Oracle specific type 
stmt.registerIndexTableOutParameter(1, 30, OracleTypes.VARCHAR, 30); 

stmt.execute(); 

そして、私のようなエラーを取得保管:誰が正しい道からそのデータ型にアクセスするためには何か説明してもらえ

Exception in thread "main" java.sql.SQLException: ORA-06550: line 1, column 13: 
PLS-00382: expression is of wrong type 
ORA-06550: line 1, column 7: 
PL/SQL: Statement ignored 

をjdbc?私のカスタムタイプは次のように番号とバイナリ整数を使用している場合

はまた、私は何をすべき:

type AssocArry IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; 

私は最後の1週間からこの問題を解決しようとすると何もありませんし、多数のスレッドに見えています。

ありがとうございました。

+0

どのOracleデータベースとOracle JDBCドライバのバージョンを使用していますか?ここで 'オラクル12cはJDBC開発者guide'で連想配列についての章があります:https://docs.oracle.com/database/121/JJDBC/oraint.htm#JJDBC28179が、Oracle 11。2ドキュメントにはどこにも言及されていませんが、古いバージョンのデータベースであってもドライバは単にそれらをサポートしていない可能性があります。 – krokodilko

答えて

1

私は自分の首を突き出ししようとJDBCからTABLE OF varchar(30) INDEX BY VARCHAR(30)として宣言されたデータ型にアクセスするための直接的な方法がないことを言っています。

Oracle JDBC documentationには、さまざまな場所で連想配列の要素タイプ(つまり、自分のタイプの最初のvarchar(30))が記述されていますが、わかっている限り、重要なデータ型については何も言及していません。さらに、連想配列が渡され、Java配列として返されることについてのドキュメントも記載されています。これは、Oracle JDBCがキーデータ型としてBINARY_INTEGERという連想配列しかサポートしていないと考えられます。

したがって、JDBCのVARCHAR2キーを使用してPL/SQL連想配列のデータにアクセスする場合は、まずデータを別のデータ型に変換することをお勧めします。

しかし、私はあなたがregisterIndexTableOutParameterにお電話でOracleTypes.NUMERICためOracleTypes.VARCHARを変更すると、あなたが書いたJDBCコードは、BINARY_INTEGERキーを使用して連想配列を処理することを期待します。 Java配列が最大のキー値とそれのような多くの要素を持っているので、要素の最大数(registerIndexTableOutParameterの2番目のパラメータ)は、このために十分な大きさであることを保証します戻っていることに注意してください。また、JDBCドライバがこれらをサポートしないように見えるので、連想配列に負またはゼロのキーがないことを確認してください。参考のため


、ここで私はINDEX BY BINARY_INTEGER作業として宣言連想配列を取得するために使用するコードです。まず、PL/SQLパッケージとボディ:

create or replace PACKAGE testLookAside as 
    type AssocArry IS TABLE OF number INDEX BY binary_integer; 
    function lookupMasterData return AssocArry; 
end testLookAside; 
/

create or replace PACKAGE BODY testLookAside as 
    function lookupMasterData return AssocArry as 
    retval AssocArry; 
    begin 
    retval(2) := 1; 
    retval(4) := 2; 
    retval(7) := 3; 
    retval(1) := 4; 
    return retval; 
    end lookupMasterData; 
end testLookAside; 
/

第二に、Javaクラス:私は、Javaクラスを実行すると

import java.math.BigDecimal; 
import java.sql.*; 
import java.util.Arrays; 
import oracle.jdbc.OracleCallableStatement; 
import oracle.jdbc.OracleTypes; 

public class AssocArrayTest { 
    public static void main(String[] args) throws Exception { 
     Connection c = DriverManager.getConnection("url", "user", "password"); 
     OracleCallableStatement s = (OracleCallableStatement)c.prepareCall("{? = call testLookAside.lookupMasterData }"); 
     s.registerIndexTableOutParameter(1, 30, OracleTypes.NUMERIC, 0); 
     s.execute(); 
     BigDecimal[] data = (BigDecimal[])s.getPlsqlIndexTable(1); 
     System.out.println(Arrays.toString(data)); 
    } 
} 

、私は次のような出力が得られます。

[4, 1, null, 2, null, null, 3] 
+0

ご返信いただきありがとうございます。あなたの提案に従って、私はコードをBINARY_INTEGERを使うように変更しました。 'TYPE NUMBER_ARRAY_TYPEはBINARY_INTEGER BYのNUMBER INDEXのテーブルです。 'また、このgetOracleStatement(cstmt).registerIndexTableOutParameter(bindOffset、m_maxLen、OracleTypes.NUMERIC、m_elemMaxLen);のようにregisterIndexTableOutParameterを変更しました。私はまだ同じ例外が表示されます:-( – boxfish

+0

@ boxfish:私の答えのサンプルコードに追加しましたが、私は主なデータ型として 'BINARY_INTEGER'を使ってPL/SQL連想配列を検索しました。 –