2017-09-15 3 views
1

here으로 표시된 접근 방식을 사용하여 Oracle PL/SQL 컬렉션 (연관 배열)을 정렬하려고합니다. 연관 배열을 사용하기 위해 링크 된 페이지에서 예제를 수정했지만 일부 캐스팅 문제가있는 것 같습니다.Oracle CAST MULTISET ORA-00902 : 잘못된 데이터 유형

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; 

내가 잘못 뭐하는 거지 : 여기

내 코드는?

시간이 무엇인지 모르는 SQL EngineSQL Engine 작동하기 때문에 당신은 select에서 tableassociative array을 사용할 수 없습니다
+0

연관 배열에'MULTISET'을 사용할 수 없습니다. –

답변

0

associative array, SQL EngineTable Type으로 작동하고, 필요하지 않은 수 첫째 select (select from dual) , 당신은 pl/sql engine을 통해 그것을 내가 여기에 내가 12C 전에 오라클 버전 모음 (VARCHAR에 의해 인덱스)를 주문하는 데 사용되는 사소한 해결 방법을보고 있습니다 완전성을 위해서이

.................... 
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; 
+0

고마워요! 전역 범위에 관한 문제를 제외하고 (당신이 옳다), 솔루션에서와 같이 숫자 컬렉션 대신 VARCHAR (내 원래 코드 에서처럼)로 색인 된 전역 연관 배열을 사용하는 방법이 있습니까? – serkelion

+0

아니요, 테이블 형식 만 사용해야합니다. – Vecchiasignora

+0

@serkelion 12c부터 패키지 표현식에 정의 된 연관 배열에 테이블 표현식을 사용할 수 있습니다. – 0xdb

0

처럼 변경할 수 있습니다. 이 솔루션은 연관 배열 컬렉션을 사용자 지정 테이블 형식으로 바꿉니다 (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; 

희망이 도움이됩니다.