Get table return value from PL/SQL stored function using JDBC

喜你入骨 提交于 2021-01-27 06:30:53

问题


I have a PL/SQL stored function which returns a table of integers:

CREATE TYPE INT_TABLE IS TABLE OF INTEGER;

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

I wish to use JDBC to retrieve the result of this function so that I can iterate through the integers in some way, be it a ResultSet, int[], or whatever.

The function f performs modifications to the database, so it cannot be called in a query such as SELECT f(42) FROM DUAL;. The return value exists to inform the caller of the primary keys for the rows that it modified. I presumably must use a CallableStatement, but can't figure out exactly how. Taking inspiration from here, I have tried:

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

However, this resulted in java.sql.SQLException: Invalid argument(s) in call on the registerOutParameter line. I haven't been able to determine what this error actually means, as the docs are quite general on the exceptions that may be thrown.

I've spent hours googling and am at quite a loss as to how to proceed. Is it possible to extract a table type into Java? If not, is there some other way of returning multiple integers from the PL/SQL function that can be extracted into Java?


回答1:


I'm answering my own question after figuring it out.

I was very close to the solution; I'd just missed specifying the type name in the registerOutParameter call. The final solution therefore looks like:

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

This is native JDBC and does not require any of the Oracle extensions.

One other thing that tripped me up was the structure of this ResultSet. It contains two columns; the first is the index and the second is the value (documentation link). Therefore, if you want to extract the elements of the array, you need to call rs.getInt(2) for each row rather than rs.getInt(1).

If one instead wanted the result as a plain array rather than a ResultSet, the corresponding type is java.math.BigDecimal, so it would be

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


来源:https://stackoverflow.com/questions/58964619/get-table-return-value-from-pl-sql-stored-function-using-jdbc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!