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);    

我们通过访问USER_TAB_COLUMNS收到ORA-01031错误!

我们将查询更改为

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时将表达式值连接起来

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')* /时,一切正常。

我们联系了oracle支持。我们希望这个BUG我们能尽快解决。

我希望这对其他人有帮助。

您有类似的问题吗?

亲切的问候

马塞尔

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)