如何通过 JDBC 调用返回 UDO 并解释该结果的 PL/SQL 函数?

Posted

技术标签:

【中文标题】如何通过 JDBC 调用返回 UDO 并解释该结果的 PL/SQL 函数?【英文标题】:How do I call by JDBC a PL/SQL function that returns an UDO and interpret that result? 【发布时间】:2011-11-27 15:49:06 【问题描述】:

假设我的 UDO(用户定义对象)是:

create or replace
TYPE UDO_PERSON AS object (NAME VARCHAR2(100), AGE INTEGER);

我有一个 PL/SQL 函数

create or replace
FUNCTION CREATE_A_PERSON(NAME VARCHAR2)
RETURN UDO_PERSON
AS  
    AGE INTEGER;
BEGIN

    SELECT dbms_random.value(1,100) INTO AGE FROM DUAL;
    RETURN NEW UDO_PERSON(NAME, AGE);

END CREATE_A_PERSON;

我测试了以下方法并且它有效,并且有一些方法可以“解析”结果

...

String select = "SELECT CREATE_A_PERSON('my name') FROM DUAL";
Statement stmt=conn.createStatement();
ResultSet rs= stmt.executeQuery(select);
rs.next();

java.sql.Struct jdbcStruct = (java.sql.Struct)rs.getObject(1);

Object[] attrs = jdbcStruct.getAttributes();
for(int i=0;i<attrs.length;i++)
    System.out.println("attrs["+i+"] "+attrs[i].toString());


... 

但我想使用的是CallableStatement,例如:

String procedure = "? = call CREATE_A_PERSON (?)";
CallableStatement statement = conn.prepareCall(procedure);

statement.registerOutParameter(1, java.sql.Types.STRUCT); // I tested with OTHER, JAVA_OBJECT 
statement.setString(2, "Youre name");

ResultSet rs= statement.executeQuery(); // tried also with execute() and then statement.getObject()...still nothing
java.sql.Struct jdbcStruct = (java.sql.Struct)rs.getObject(1);

...

所以最后一段代码会根据我使用的java.sql.Type、execute 方法的类型抛出不同类型的异常。

有人吗?我搜索了 Oracle 文档,但发现它非常混乱。

【问题讨论】:

在系统允许的情况下(我相信最早是发帖后的8小时),请将问题的答案从你的问题中删除,并作为真实答案重新发布。 【参考方案1】:

所以解决办法是

String procedure = "? = call CREATE_A_PERSON (?)";
CallableStatement statement = conn.prepareCall(procedure);
statement.registerOutParameter(1, java.sql.Types.STRUCT, "UDO_PERSON");
statement.setString(2, "YOURE NAME");
statement.execute();
...

旧线:

statement.registerOutParameter(1, java.sql.Types.STRUCT);

换行:

statement.registerOutParameter(1, java.sql.Types.STRUCT, "UDO_PERSON");

从这里您只需“解析”java.sql.Struct 对象。集合也是如此(尽管我只测试了VARRAY_OF_NUM),您需要使用带有三个参数的registerOutParameter,否则您会看到一些异常,例如“ORA-03115:不支持的网络数据类型或表示”。显然,如果您的 PL/SQL 函数返回 VARRAY,请使用 statement.registerOutParameter(1, OracleTypes.ARRAY, "YOURE_VARRAY_TYPE");

【讨论】:

【参考方案2】:

让你的函数成为table 函数怎么样? 这将允许您:

select CREATE_A_PERSON('Daniel') from dual;

并收到一个包含两列 (AGE, NAME) 的表格,其中包含当前人员的详细信息。

【讨论】:

这不是我要找的...我找到了解决方案,但我还不能发布我自己问题的答案

以上是关于如何通过 JDBC 调用返回 UDO 并解释该结果的 PL/SQL 函数?的主要内容,如果未能解决你的问题,请参考以下文章

在Spark中如何使用UDO作为参数调用UDF以避免二进制错误

MYSQL 之 JDBC: 增删改查通过ResultSet执行查询操作

通过 JDBC 调用 Sybase 存储过程时的空结果集

Java JDBC 从不同的调用返回重复的结果集

如何使用 JDBC 调用 PostgreSQL 存储过程

如何从 jdbc 调用存储的函数?