#cursor #oracle19c #sys-refcursor #ora-01031
#курсор #oracle19c #sys-refcursor #ora-01031
Вопрос:
у нас есть несколько проблем с курсорами и 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);
У нас нет ошибки! Что здесь делает oracle?
Проблема 2 «ORA-01001» Теперь мы используем ALL_TAB_COLUMNS и объединяем со СЛУЧАЕМ, КОГДА значения выражения
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. Что здесь делает oracle? Потерян КУРСОР?
Мы добавляем опцию /* 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’) */, все работает нормально.
Мы связались со службой поддержки oracle. Мы надеемся, что эта ОШИБКА будет устранена в ближайшее время.
Я надеюсь, что это полезно для других.
У вас есть похожие проблемы?
С уважением
Марсель