gpt4 book ai didi

java - JDBC:Oracle 存储过程返回嵌套表

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:55:58 32 4
gpt4 key购买 nike

我在 oracle(12c) 中有一个存储过程:

PROCEDURE work(a OUT VARCHAR2, b OUT SYS_REFCURSOR)

当我调用该过程时,游标的结果包含行,该行由一些原始值 + 自定义类型组成:

CREATE TYPE ELEM AS OBJECT(ElemID INTEGER))
CREATE TYPE LIST AS TABLE OF ELEM

所以,结果是这样的:

vcursor:
------------------
COL1 COL2 LIST
------------------
A B LIST([ELEM],[ELEM])
C D LIST([ELEM],[ELEM],[ELEM])
E F LIST([ELEM])

Collection 有教程Oracle tutorial (如果链接丢失,请在谷歌上搜索“Working with Oracle Collections”)。到目前为止,本教程对我没有任何帮助。

这是我在 java 中所做的:

Connection conn = ...
CallableStatement statement = conn.prepareCall("{call work()}");
statement.registerOutParameter(1, OracleTypes.VARCHAR);
statement.registerOutParameter(2, OracleTypes.CURSOR);
statement.execute();

ResultSet rs = statement.getResultSet(2);
// here should be the code which retrieves the nested table elements
rs.next()
Array list = rs.getArray(3); //oracle.sql.ARRAY
Object[] elems = (Object[]) list.getArray(); // doesn't work
// I also tried list.getResultSet()

在调试下,我确实看到如果我转换为 oracle.sql.ARRAY 并调用 getOracleArray(),那么我会看到正确的大小和带有 Struct[] 的 Datum[] 数组,但是普通的 sql 方法没有给我任何结果。例如,array 中的 getResultSet 返回一个 ResultSet,next 总是返回 true,但没有元数据和实际数据。 getArray() 返回 numElements = -1 等的数组。

我尝试使用 typeMap 但没有成功:

Map map = conn.getTypeMap();
map.put("ELEM", Elem.class);
//map.put("SCHEMA.ELEM", Elem.class);
//map.put("LIST", Elem.class);
//map.put("SCHEMA.LIST", Elem.class);
conn.setTypeMap(map);

请帮助和建议。提前致谢。

最佳答案

恐怕我正在努力重现您所看到的行为。我试图整理一些可以重现您的问题的代码,但它奏效了。代码如下,希望对你有用。

我为类型 ELEM 使用了一个类型映射条目,但没有为 LIST 使用。我也找不到 CallableStatement 接口(interface)上的 getResultSet(int) 方法,所以我改用 getObject(int) 并将其转换为 ResultSet.

以防万一,我在 Windows 10 x64 上使用 Oracle 11g XE 11.2.0.2.0、Java 1.8.0_60、ojdbc7.jar 版本 12.1.0.2.0。我还尝试了 ojdbc6.jar 和 ojdbc5.jar 的版本,它们的结果相同。

SQL:

CREATE TYPE elem AS OBJECT(ElemID INTEGER);
/

CREATE TYPE list AS TABLE OF elem;
/

CREATE OR REPLACE PROCEDURE work(a OUT VARCHAR2, b OUT SYS_REFCURSOR)
AS
BEGIN
a := 'test 1234';
OPEN b FOR
SELECT 'A' AS col1, 'B' AS col2, list(elem(14), elem(17)) FROM DUAL
UNION ALL
SELECT 'C' AS col1, 'D' AS col2, list(elem(8), elem(4), elem(11)) FROM DUAL
UNION ALL
SELECT 'E' AS col1, 'F' AS col2, list(elem(-1)) FROM DUAL;
END work;
/

元素.java:

import java.sql.*;

public class Elem implements SQLData {

private Integer elementId;

public String getSQLTypeName() { return "ELEM"; }

public void readSQL(SQLInput input, String typeName) throws SQLException {
elementId = input.readInt();
}

public void writeSQL(SQLOutput output) {
throw new UnsupportedOperationException();
}

public String toString() {
return "<Element " + elementId + ">";
}
}

JDBCStructs.java:

import java.sql.*;
import java.util.*;

public class JDBCStructs {
public static void main(String[] args) throws Exception {
Connection c = ...

Map<String, Class<?>> map = c.getTypeMap();
map.put("ELEM", Elem.class);
c.setTypeMap(map);

CallableStatement cs = c.prepareCall("{call work(?, ?)}");
cs.registerOutParameter(1, Types.VARCHAR);
cs.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);
cs.execute();
String a = cs.getString(1);
System.out.println("Got string " + a);
ResultSet rSet = (ResultSet)cs.getObject(2);
while (rSet.next()) {
String col1 = rSet.getString(1);
String col2 = rSet.getString(2);
Array list = (Array)rSet.getObject(3);
System.out.println("Got " + col1 + ", " + col2 + " and " + Arrays.toString((Object[])list.getArray()));
}
}
}

输出:

Got string test 1234
Got A, B and [<Element 14>, <Element 17>]
Got C, D and [<Element 8>, <Element 4>, <Element 11>]
Got E, F and [<Element -1>]

关于java - JDBC:Oracle 存储过程返回嵌套表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34749096/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com