问题
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