在數據庫中三個Oracle定製類型(簡化的)如下:閱讀來自通過存儲過程返回一個STRUCT的ARRAY
create or replace TYPE T_ENCLOSURE AS OBJECT(
ENCLOSURE_ID NUMBER(32,0),
ENCLOSURE_NAME VARCHAR2(255 BYTE),
ANIMALS T_ARRAY_ANIMALS,
MEMBER FUNCTION CHECK_IF_RED RETURN BOOLEAN
);
create or replace TYPE T_ARRAY_ANIMALS is TABLE OF T_ANIMAL;
create or replace TYPE T_ANIMAL AS OBJECT(
ANIMAL_ID NUMBER(32,0),
NUMBER_OF_HAIRS NUMBER(32,0)
);
和一個功能,即建立對象樹
FUNCTION GET_ENCLOSURE (f_enclosure_id zoo_schema.ENCLOSURE_TABLE.ENCLOSURE_ID%TYPE) RETURN T_ENCLOSURE
AS
v_ENC T_ENCLOSURE;
v_idx pls_integer;
BEGIN
v_ENC := T_ENCLOSURE(
f_enclosure_id,
NULL,
T_ARRAY_ANIMALS(T_ANIMAL(NULL,NULL))
);
SELECT ENCLOSURE_NAME
INTO v_ENC.ENCLOSURE_NAME
FROM ENCLOSURE_TABLE WHERE ENCLOSURE_ID = f_ENCLOSURE_ID;
SELECT
CAST(MULTISET(
SELECT ANIMAL_ID, NUMBER_OF_HAIRS
FROM ANIMAL_TABLE
WHERE ENCLOSURE_ID = f_ENCLOSURE_ID
) AS T_ARRAY_ANIMALS
)
INTO v_ENC.ANIMALS
FROM dual;
RETURN v_ENC;
END;
現在我想調用GET_ENCLOSURE
函數,並在我的Java代碼中使用它的結果T_ENCLOSURE
對象。
// prepare the call
Connection connection = MyConnectionFactory.getConnection(SOME_CONNECTION_CONFIG);
CallableStatement stmt = connection.prepareCall("{? = call zoo_schema.zoo_utils.GET_ENCLOSURE(?)}");
stmt.registerOutParameter(1, OracleTypes.STRUCT, "zoo_schema.T_ENCLOSURE");
stmt.setInt(2, 6); // fetch data for ENCLOSURE#6
// execute function
stmt.executeQuery();
// extract the result
Struct resultStruct = (Struct)stmt.getObject(1); // java.sql.Struct
我可以通過
Integer id = ((BigInteger)resultStruct.getAttributes()[0]).intValue(); // works for me
String name = (String)resultStruct.getAttributes()[1]); // works for me
訪問ID和NAME不過,我似乎無法得到動物
resultStruct.getAttributes()[2].getClass().getCanonicalName(); // oracle.sql.ARRAY
ARRAY arrayAnimals = (ARRAY)jdbcStruct.getAttributes()[2];
arrayAnimals.getArray(); // throws a java.sql.SQLException("Internal Error: Unable to resolve name")
我有一點試驗和列表錯誤在這裏包括
OracleConnection oracleConnection = connection.unwrap(OracleConnection.class);
STRUCT resultOracleStruct = (STRUCT) stmt.getObject(1); // oracle.sql.STRUCT
oracleConnection.createARRAY("zoo_schema.T_ARRAY_ANIMALS", resultOracleStruct.getAttributes()[2]) // throws an SQLException("Fail to convert to internal representation: [email protected]")
但是也沒有運氣。
如何將動物列表變成List<TAnimal>
?
我不認爲有直接或標準的方式從JDBC中檢索TABLE OF數組(一個plsql類型)。通常,您只能調用從Java(JDBC)返回SQL對象的過程,而不是PlSQl對象(即使它們被包裝在OBJECT類型中,您將無法檢索它們)。我看到2個可能的解決方案,但1)將你的對象錶轉換爲一個字符串(用逗號等分隔)並在客戶端手動解析它2)嘗試使用一些特定於Oracle的未公開的API(例如http://stackoverflow.com/questions/37767761/plsql-how-to-return-associative-array-to-java?rq = 1) –
一個非常特定於Oracle的解決方案將會非常好。該項目中的數據庫不會被更改。 – DerMike
您可以提供GET_ENCLOSURE的代碼進行調試嗎? –