1

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

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

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

你有类似的问题吗?

亲切的问候

马塞尔

4

0 回答 0