是否可以将多个Oracle ref游标分配给一个

时间:2020-08-05 17:50:54

标签: oracle spring-data-jpa ref-cursor

如标题中所述,我想知道是否可以将多个引用游标(在Oracle存储过程中)分配给一个: 像下面的代码: ....

    create or replace procedure assign_ref_cursor(result_cur out sys_refcursor)
    as
    cursor1 sys_refcursor;
    cursor2 sys_refcursor;
    cursor3 sys_refcursor;
    
    -- expected result:
    result_cur[0] = cursor1
    result_cur[1] = cursor2
    result_cur[2] = cursor3
...
return  result_cur;

... 好吧,那就是将每个ref_cursor的全部结果都放在一个中。

之所以这样,是因为我正在使用Spring数据JPA从存储过程中检索数据(多个ref游标)。但是显然,尽管有几天的Google搜索,但仍然没有解决方案可以使用javax.persistence.storedprocedurequery检索多个引用游标...

因此,我想到了将Oracle存储过程更改为仅返回一个ref_cursor的解决方案,该ref_cursor“聚合”了不同的ref_cursor。

在亚历克斯(Alex)的问题之后,这是更新

我尝试使用以下命令调用三个OUT ref游标参数:

StoredProcedureQuery proc = entityManager.createStoredProcedureQuery("myStoredProc");
proc.registerStoredProcedureParameter("cursor1", void.class, ParameterMode.REF_CURSOR);
proc.registerStoredProcedureParameter("cursor2", void.class, ParameterMode.REF_CURSOR);
...
List<Object[]> listOfObjects =  proc.getResultList();

但是 listOfObjects 仅包含 cursor1 的内容 无法获取 cursor2 ...

的内容

2 个答案:

答案 0 :(得分:1)

如果您当前有类似的东西:

open cursor1 for <query1>;
open cursor2 for <query2>;
open cursor3 for <query3>;

然后您可以将它们合并为cursor expressions的一个结果:

open result_cur for
  select cursor(<query1>) as cursor1,
         cursor(<query2>) as cursor2,
         cursor(<query3>) as cursor3
  from dual;

如果您要返回其他数据,则还可以包括更多“普通”列,并针对实际表而不是对偶进行主查询。

答案 1 :(得分:0)

这可能会有所帮助:

通过从 Hibernate EntityManager 获取连接然后使用 CallableStatement 来解决。

// Session = org.hibernate.Session
// entityManager = javax.persistence.EntityManager
Session session = entityManager.unwrap(Session.class);
session.doWork(new Work() {
@Override
public void execute(Connection con) throws SQLException {
    // do something useful
    try (CallableStatement cs = con.prepareCall("{CALL TEST_PACKAGE.GETCURSORS(?,?,?)}")) {
        cs.setInt(1, 1);
        cs.registerOutParameter(2, OracleTypes.CURSOR);
        cs.registerOutParameter(3, OracleTypes.CURSOR);
        cs.execute();
        ResultSet rs = (ResultSet) cs.getObject(2);
        ResultSet rs1 = (ResultSet) cs.getObject(3);
        while (rs.next()) {
            int a = rs.getInt(1);
            System.out.println(a);
        }
        while (rs1.next()) {
            int b = rs1.getInt(1);
            System.out.println(b);
        }
    }
}