Можно ли назначить несколько указателей Oracle ref одному

Как сказано в заголовке, я хотел бы знать, можно ли назначить несколько курсоров ref (в Oracle Stored Procedure) одному: Как следующий код: ....

    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 с помощью javax.persistence.storedprocedurequery ... несмотря на дни поиска в Google ...

Итак, я придумал решение изменить хранимую процедуру Oracle, чтобы она возвращала только один ref_cursor, который объединяет разные ref_cursor.

После вопроса Алекса, вот ОБНОВЛЕНИЕ

Я попытался вызвать три параметра курсора 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 ...


person Zamboo    schedule 05.08.2020    source источник
comment
Откуда берутся три курсора - открываете ли вы их в рамках этой процедуры?   -  person Alex Poole    schedule 05.08.2020
comment
Почему нельзя вызвать процедуру с тремя параметрами курсора OUT ref? Похоже, что это поддерживается; или это ограничение Strong / JPA?   -  person Alex Poole    schedule 05.08.2020
comment
Спасибо, Алекс за ваш ответ: я сделал обновление, чтобы ответить на ваш вопрос.   -  person Zamboo    schedule 06.08.2020


Ответы (2)


Если у вас сейчас есть что-то вроде:

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

тогда вы можете объединить их как выражения курсора в одном результате:

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

Если вы возвращаете другие данные, вы также можете включить больше «обычных» столбцов и, конечно же, сделать этот основной запрос к реальной таблице, а не к двойной.

person Alex Poole    schedule 05.08.2020
comment
Я попробовал ваше решение: мне удалось объединить ref_cursors в один результат. Но из части java у меня есть org.hibernate.MappingException: No Dialect mapping для типа JDBC: -10. - person Zamboo; 06.08.2020

Это может быть полезно:

Обходной путь путем получения соединения от 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);
        }
    }
}
person Shubhankar Sarkar    schedule 22.06.2021