CUSOR / SYS_REFCUSOR Проблемы / ОШИБКА в Oracle 19c

У нас есть несколько проблем с курсорами и SYS_REFCURSOR. В версии 12.2.0.1 все работает нормально. Мы установили новую систему с 19.8.0.0, и ничего не было перенесено.

Мы используем функцию для объединения каждого значения в строке, заданной запросом, в строку в виде списка, разделенного запятыми. Запрос возвращает объект CURSOR, а функция имеет переменную SYS_REFCURSOR. Внутри функции строки выбираются и объединяются.

CREATE OR REPLACE FUNCTION JOIN_1(P_CURSOR SYS_REFCURSOR, P_DEL VARCHAR2 := ',') RETURN VARCHAR2 IS
    V_VALUE  VARCHAR2(4000);
    V_RESULT VARCHAR2(4000);
    PRAGMA AUTONOMOUS_TRANSACTION;
  BEGIN
    LOOP
      FETCH P_CURSOR
        INTO V_VALUE;
      EXIT WHEN P_CURSOR%NOTFOUND;
      IF V_RESULT IS NOT NULL THEN
        V_RESULT := V_RESULT || P_DEL;
      END IF;
      V_RESULT := V_RESULT || V_VALUE;
    END LOOP;
    CLOSE P_CURSOR;
    RETURN V_RESULT;
  END JOIN_1;

Задача 1 "ORA-01031"

Мы используем этот запрос, чтобы проиллюстрировать нашу первую проблему:

SELECT * FROM (SELECT JOIN_1(CURSOR (SELECT COLUMN_NAME FROM USER_TAB_COLUMNS WHERE ROWNUM < 15),  ',') GV FROM DUAL);    

Мы получаем ошибку ORA-01031 при доступе к USER_TAB_COLUMNS!

Меняем запрос на

SELECT * FROM (SELECT JOIN_1(CURSOR (SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS WHERE ROWNUM < 15),  ',') GV FROM DUAL);    

У нас нет ошибки! Что здесь делает оракул?

Проблема 2 "ORA-01001". Теперь мы используем ALL_TAB_COLUMNS и объединяем значения выражения CASE WHEN

SELECT CASE
         WHEN LENGTH(GV) = 1 THEN ' '
         ELSE GV
        END GV
  FROM (SELECT JOIN_1(CURSOR (SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS WHERE ROWNUM < 15),  ',') GV FROM DUAL);

Получаем ORA-01001. Что здесь делает оракул? Потерянный КУРСОР?

Добавляем параметр /*+ NO_MERGE */

SELECT CASE
         WHEN LENGTH(GV) = 1 THEN ' '
         ELSE GV
        END GV
  FROM (SELECT JOIN_1(CURSOR (SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS WHERE ROWNUM < 15),  ',') GV FROM DUAL);

У нас нет ошибки! Почему?

Когда мы используем подсказку /*+ OPTIMIZER_FEATURES_ENABLE('12.2.0.1') */, все работает нормально.

Мы связались со службой поддержки оракула. Мы надеемся, что эта ОШИБКА будет решена в ближайшее время.

Я надеюсь, что это поможет другим.

У вас есть похожие проблемы?

С уважением

Марсель

0 ответов

Другие вопросы по тегам