java - 如何将table%rowtype的oracle pl/sql out参数引用为java中的对象
Posted
技术标签:
【中文标题】java - 如何将table%rowtype的oracle pl/sql out参数引用为java中的对象【英文标题】:how to reference an oracle pl/sql out parameter of table%rowtype as an object in java 【发布时间】:2011-12-13 01:39:47 【问题描述】:在 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 参数?我知道我可以改用游标,但我认为这不是一个好习惯,因为我只检索一行。此外,我需要从 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
【问题讨论】:
【参考方案1】:这里的“rowtype”是Oracle PL/SQL 特有的类型,我不认为它会被JDBC 支持。快速搜索 oracle 论坛(谷歌“jdbc rowtype site:oracle.com”)表明相同。您最好返回一个游标,或者直接从 JDBC 执行 SQL。
【讨论】:
我是否认为虽然使用游标将保留在 Oracle 端存储所有逻辑的目标,但直接从 JDBC 执行 SQL 会执行得更快? 在JDBC中直接执行SQL比较快是对的【参考方案2】:只是一个想法, 您可以将您的函数设为流水线函数,然后像检索表格一样检索数据。 这是流水线函数的一些示例
http://www.akadia.com/services/ora_pipe_functions.html
【讨论】:
【参考方案3】:cstmt = conn.getNewCallableStatement("call MY_PLSQL_PACKAGE.MY_PROC(?,?,?)");
cstmt.setString(1, stringOutput1);
cstmt.setString(2, stringOutput2);
cstmt.registerOutParameter(3, OracleTypes.CURSOR);
cstmt.execute;
【讨论】:
【参考方案4】:很遗憾,您无法通过 JDBC 序列化 PL/SQL RECORD
类型,但您可以通过执行匿名 PL/SQL 块来解决此限制,如下所示:
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;
您现在可以使用以下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,它还解释了如何为所有 PL/SQL RECORD 类型自动生成这些 PL/SQL 块。
【讨论】:
以上是关于java - 如何将table%rowtype的oracle pl/sql out参数引用为java中的对象的主要内容,如果未能解决你的问题,请参考以下文章