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,其属性为 idtitlemessage。下面的存储过程根据提供的 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中的对象的主要内容,如果未能解决你的问题,请参考以下文章

将任意rowtype作为参数传递

对象类型中 %ROWTYPE 的解决方法

pl/sql 中的 ROWTYPE 定义

如何使用 Oracle (PL/SQL) 动态 sql 将数据查询到 %rowtype 变量中

如何使用 %ROWTYPE 获取游标值

检查 plsql 中的记录 IS NOT NULL