In Oracle 11g I have a table survey
with properties id
, title
, and message
. The stored procedure below gets a single record based on a provided ID and stores it in the provided OUT parameter.
create or replace procedure get_survey(arg_id number, obj_survey out survey%rowtype) is
begin
select * into obj_survey from survey where id = arg_id;
end get_survey;
I need to call this stored procedure from Java and I know I can begin with a CallableStatement
, but how do I pass the OUT parameter from Java considering it has to be of type survey%rowtype
? I know I can use a cursor instead but I think that's not good practice since I'm retrieveing only one row. Also, I need to create a Survey object (POJO) from the OUT parameter and return it from the method. Here's how far I've currently gotten in the code:
public Survey getSurvey(int id) throws SQLException {
CallableStatement stmt = conn.prepareCall("begin get_survey(?, ?); end;");
stmt.setInt(1, id);
stmt.registerOutParameter(2, OracleTypes.[okay what do i put here?]); // not sure about this line either
stmt.execute();
// get the out parameter, convert it to a Survey object type and return it
}
"rowtype" here is an Oracle PL/SQL-specific type, I don't think it would be supported by JDBC. A quick search of the oracle forums (google "jdbc rowtype site:oracle.com") suggests the same. You're probably better off returning a cursor, or just execute the SQL from JDBC directly.
Unfortunately, you cannot serialise a PL/SQL RECORD
type over JDBC, but you can work around this limitation by executing an anonymous PL/SQL block like this:
DECLARE
obj_survey survey%rowtype;
BEGIN
get_survey(?, obj_survey);
? := obj_survey.id;
? := obj_survey.x;
? := obj_survey.y;
...
-- continue this for all attributes in survey
END;
You can now use the following CallableStatement
:
try (CallableStatement s = conn.createCall(" [ ... above PL/SQL ... ] ")) {
s.setInt(1, id);
s.registerOutParameter(2, Types.INTEGER);
s.registerOutParameter(3, Types.VARCHAR);
s.registerOutParameter(4, Types.DATE);
...
// Repeat for all attributes
s.execute();
int id = s.getInt(2);
String x = s.getString(3);
Date y = s.getDate(4);
...
// Repeat for all attributes
}
I've recently written about this technique in a blog post , which also explains how these PL/SQL blocks can be generated automatically for all PL/SQL RECORD types.
Just an idea, You could make your function as a piplined function and then retrieve the data as if it was a table. here is some examples of piplined functions
cstmt = conn.getNewCallableStatement("{call MY_PLSQL_PACKAGE.MY_PROC(?,?,?)}");
cstmt.setString(1, stringOutput1);
cstmt.setString(2, stringOutput2);
cstmt.registerOutParameter(3, OracleTypes.CURSOR);
cstmt.execute;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.