Oracle CAST MULTISET ORA-00902:数据类型无效

时间:2017-09-15 09:09:15

标签: oracle collections plsql casting associative-array

我尝试使用提供的方法here对Oracle PL / SQL集合(关联数组)进行排序。我修改了链接页面中的示例以使用关联数组,但我想我有一些投射问题。

这是我的代码:

DECLARE

   TYPE TABLE_TYPE IS TABLE OF NUMBER INDEX BY VARCHAR2(10);
   table_in   TABLE_TYPE;
   table_out  TABLE_TYPE;

BEGIN

    -- 1. Populating the collection with random numbers between 1 and 50
    FOR i IN 1..9 LOOP

      SELECT ROUND(DBMS_RANDOM.VALUE(1,50))
      INTO table_in('key-'||i)
      FROM DUAL;      

    END LOOP;

    -- 2. Trying to order the collection -> throws ORA-00902: invalid datatype
    SELECT CAST (MULTISET(
      SELECT * FROM TABLE(table_in)
      ORDER BY 2
      ) AS TABLE_TYPE
    )
    INTO table_out
    FROM DUAL;

END;

我做错了什么?

2 个答案:

答案 0 :(得分:0)

您无法在associative array中使用table作为select,因为该时间有效SQL Engine而且SQL Engine不知道associative array是什么{ {1}},SQL Engine只适用于Table Type,您不需要先selectselect from dual),您可以通过pl/sql engine进行操作,改变它

....................
TYPE NumbersTableType IS TABLE OF NUMBER; -- it must be in global types, not in your local package
....................

DECLARE

   table_in   NumbersTableType := NumbersTableType();
   table_out  NumbersTableType;

BEGIN

    -- 1. Populating the collection with random numbers between 1 and 50
    FOR i IN 1..9 LOOP
      table_in.Extend;
      table_in(i):=ROUND(DBMS_RANDOM.VALUE(1,50));
    END LOOP;

    SELECT CAST (MULTISET(
      SELECT * FROM TABLE(table_in)
      ORDER BY 1
      ) AS NumbersTableType
    )
    INTO table_out
    FROM DUAL;

END;

答案 1 :(得分:0)

为了完整起见,我将在此处报告我在12c之前在Oracle版本中用于订购集合(由varchar索引)的简单解决方法。该解决方案只是将关联数组集合替换为自定义表类型(以使其对SQL引擎可见)。

CREATE OR REPLACE TYPE MY_TABLE_TYPE_OBJ AS OBJECT (
  THE_KEY VARCHAR2(10),
  THE_VALUE NUMBER
);
/
CREATE OR REPLACE TYPE MY_TABLE_TYPE IS TABLE OF MY_TABLE_TYPE_OBJ;
/

DECLARE

   my_key VARCHAR2(10);
   table_in   MY_TABLE_TYPE := MY_TABLE_TYPE();
   table_out  MY_TABLE_TYPE := MY_TABLE_TYPE();

BEGIN

    -- Creating an unsorted collection
    FOR i IN 1..9 LOOP
      table_in.EXTEND;
      table_in(i) := MY_TABLE_TYPE_OBJ(
        'key-'||i,
         ROUND(DBMS_RANDOM.VALUE(1,50))
      );
    END LOOP;

    -- Sorting the collection
    SELECT CAST (MULTISET(
      SELECT * FROM TABLE(table_in)
      ORDER BY 2
      ) AS MY_TABLE_TYPE
    )
    INTO table_out
    FROM DUAL;

END;

希望这会有所帮助。