2017-09-15 2 views
1

J'essaie de trier une collection Oracle PL/SQL (un tableau associatif) en utilisant l'approche présentée here. J'ai modifié l'exemple de la page liée afin d'utiliser un tableau associatif , mais je suppose que j'ai quelques problèmes de moulage.Oracle CAST MULTISET ORA-00902: type de données invalide

Ici, il est mon code:

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; 

Qu'est-ce que je fais mal?

+0

Vous ne pouvez pas utiliser 'MULTISET' sur des tableaux associatifs. –

Répondre

0

Vous ne pouvez pas utiliser associative array comme table dans select, parce que le temps travaille SQL Engine et SQL Engine ne sait pas ce qui est associative array, SQL Engine ne peut fonctionne avec Table Type, et vous ne avez pas besoin premier select (select from dual) , vous pouvez le faire via pl/sql engine, changer comme ça

.................... 
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

Merci beaucoup! Mis à part le problème de la portée globale (vous avez certainement raison), existe-t-il un moyen d'utiliser un tableau associatif global indexé par un VARCHAR (comme dans mon code original) au lieu d'une collection numérique (comme dans votre solution)? – serkelion

+0

NON, Il devrait être utilisé uniquement par type de table – Vecchiasignora

+0

@serkelion Depuis 12c, il est possible d'utiliser l'expression de table avec les tableaux associatifs définis dans la spécification du package. – 0xdb

0

pour être complet, je vais signaler ici la solution triviale je commander une collection (index par varchar) dans la version Oracle avant 12c. La solution remplace simplement la collection de tableaux associatifs par un type Table personnalisé (afin de le rendre visible à SQL Engine).

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; 

Espérons que cela aide.