如何在java中引用表%rowtype的oracle pl/sql out参数作为对象

如何在java中引用表%rowtype的oracle pl/sql out参数作为对象,java,oracle,jdbc,plsql,Java,Oracle,Jdbc,Plsql,在Oracle 11g中,我有一个表survey,其中包含属性id、title和message。下面的存储过程根据提供的ID获取一条记录,并将其存储在提供的OUT参数中 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_surve

在Oracle 11g中,我有一个表
survey
,其中包含属性
id
title
message
。下面的存储过程根据提供的ID获取一条记录,并将其存储在提供的OUT参数中

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;
我需要从Java调用这个存储过程,我知道我可以从
CallableStatement
开始,但是考虑到它必须是
survey%rowtype
类型,我如何从Java传递参数呢?我知道我可以使用光标,但我认为这不是一个好的做法,因为我只检索一行。另外,我需要从OUT参数创建一个测量对象(POJO),并从方法返回它。以下是我目前在代码方面取得的进展:

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”是Oracle PL/SQL特定的类型,我认为JDBC不支持它。快速搜索oracle论坛(google“jdbc行类型站点:oracle.com”)也会得出同样的结论。您最好返回一个游标,或者直接从JDBC执行SQL。

只是一个想法, 您可以将函数设置为管道函数,然后像检索表一样检索数据。 下面是一些管道函数的示例


不幸的是,您无法通过JDBC序列化PL/SQL
记录
类型,但您可以通过执行以下匿名PL/SQL块来绕过此限制:

声明
obj_调查%行类型;
开始
获取测量(?,obj测量);
? := obj_survey.id;
? := obj_survey.x;
? := obj_survey.y;
...
--对测量中的所有属性继续此操作
结束;
现在可以使用以下
CallableStatement

try(CallableStatement s=conn.createCall(“[…高于PL/SQL…]”){
s、 setInt(1,id);
s、 registerOutParameter(2,类型.INTEGER);
s、 registerOutParameter(3,Types.VARCHAR);
s、 registerOutParameter(4,type.DATE);
...
//对所有属性重复此操作
s、 执行();
int id=s.getInt(2);
字符串x=s.getString(3);
日期y=s.getDate(4);
...
//对所有属性重复此操作
}

,这也解释了如何为所有PL/SQL记录类型自动生成这些PL/SQL块。

我认为,虽然使用游标将保留在Oracle端存储所有逻辑的目标,但直接从JDBC执行SQL会执行得更快吗?直接在JDBC中执行SQL会更快,这是正确的
cstmt = conn.getNewCallableStatement("{call MY_PLSQL_PACKAGE.MY_PROC(?,?,?)}");
       cstmt.setString(1, stringOutput1);
       cstmt.setString(2, stringOutput2);
       cstmt.registerOutParameter(3, OracleTypes.CURSOR);
       cstmt.execute;