【问题标题】:Is it possible to assign multiple Oracle ref cursor to one是否可以将多个 Oracle 引用游标分配给一个
【发布时间】:2020-08-05 17:50:54
【问题描述】:

正如标题中所说,我想知道是否可以将多个引用游标(在 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 data JPA 从存储过程中检索数据(多个引用游标)。但显然没有使用 javax.persistence.storedprocedurequery 检索多个引用光标的解决方案......尽管谷歌搜索了几天......

所以我想出了将 Oracle 存储过程更改为仅返回一个 ref_cursor 的解决方案,即“聚合”不同的 ref_cursor。

根据 Alex 的问题,这里是 UPDATE

我尝试使用以下方法调用三个 OUT 引用光标参数:

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的内容...

【问题讨论】:

  • 三个光标从何而来 - 您是在该过程中打开它们吗?
  • 为什么不能调用带有三个 OUT ref 游标参数的过程? That seems to be supported;还是强/JPA 限制?
  • 感谢 Alex 的回复:我做了更新以回复您的问题。

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


【解决方案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;

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

【讨论】:

  • 我尝试了您的解决方案:我将 ref_cursors 组合成一个结果。但从 java 部分,我有一个“org.hibernate.MappingException:JDBC 类型没有方言映射:-10”。
【解决方案2】:

这可能会有所帮助:

解决方法是从 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);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    • 2018-03-22
    相关资源
    最近更新 更多