使用JDBC从PL / SQL存储函数获取表返回值

问题描述 投票:3回答:1

我有一个PL / SQL存储的函数,该函数返回一个整数表:

CREATE TYPE INT_TABLE IS TABLE OF INTEGER;

CREATE FUNCTION f (someParam IN INTEGER) RETURN INT_TABLE IS ...

我希望使用JDBC来检索此函数的结果,以便可以以某种方式遍历整数,无论​​是ResultSetint[]还是其他。

函数f对数据库进行了修改,因此无法在诸如SELECT f(42) FROM DUAL;的查询中调用它。该返回值的存在是为了将其修改的行的主键通知给调用者。我大概必须使用CallableStatement,但无法确切知道如何使用。从here获得灵感,我尝试过:

CallableStatement cs = conn.prepareCall("{? = call f(42)}");
cs.registerOutParameter(1, Types.ARRAY);
cs.execute();
ResultSet rs = cs.getArray(1).getResultSet();

但是,这导致java.sql.SQLException: Invalid argument(s) in call行上出现registerOutParameter。我无法确定此错误的实际含义,因为文档对于可能引发的异常非常笼统。

我花了数小时的时间进行谷歌搜索,但对如何进行操作却感到茫然。是否可以将表类型提取到Java中?如果没有,还有其他方法可以从可以提取到Java中的PL / SQL函数返回多个整数吗?

java oracle jdbc plsql
1个回答
0
投票

我想出自己的问题后便回答了。

我非常接近解决方案;我只是想念在registerOutParameter调用中指定类型名称。因此,最终的解决方案如下所示:

cs = conn.prepareCall("{? = call f(42)}");
cs.registerOutParameter(1, Types.ARRAY, "INT_TABLE");
cs.execute();
ResultSet rs = cs.getArray(1).getResultSet();

这是本机JDBC,不需要任何Oracle扩展。

令我震惊的另一件事是此ResultSet的结构。它包含两列;第一个是索引,第二个是值(documentation link)。因此,如果要提取数组的元素,则需要为每行调用rs.getInt(2),而不是rs.getInt(1)

如果不是将结果作为纯数组而不是ResultSet,则对应的类型是java.math.BigDecimal,所以它是

...
cs.execute();
BigDecimal[] array = (BigDecimal[])(cs.getArray(1).getArray());

-1
投票

是的,从oracle可以返回整数或其他类型的表。我认为,您需要定义oracle类型

订购时:1.创建类型和功能

CREATE TYPE array_int IS TABLE OF INTEGER;

CREATE OR REPLACE FUNCTION get_array (v_id IN INTEGER) 
RETURN array_int
IS
res array_int := array_int(1,2,3,4);
begin 
  return res; 
end;

和Java

    ArrayList r_list = new ArrayList();          
    ArrayDescriptor arrayInt = ArrayDescriptor.createDescriptor("ARRAY_INT", con); //to oracle type
    ARRAY iarray = new ARRAY(arrayInt, con, r_list.toArray());
    OracleCallableStatement cst = (OracleCallableStatement) con.prepareCall(
            "{call ?:= get_array(?)");
    cst.registerOutParameter(1, OracleTypes.ARRAY, "ARRAY_INT");
    cst.setInt(2, 1);
    cst.execute();
    iarray = cst.getARRAY(1);
    cst.close();

    Object[] pObjects = (Object[]) iarray.getArray();
    for (int i = 0; i < pObjects.length; i++) {
        System.out.print(pObjects[i]);
    }
© www.soinside.com 2019 - 2024. All rights reserved.