2017-09-15 3 views
1

hereの方法を使用してOracle PL/SQLコレクション(結合配列)をソートしようとしています。 連想配列を使用するために、リンクされたページの例を変更しましたが、キャスティングに問題があると思います。Oracle CASTマルチセット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が働いているので、あなたは、 selecttableとして associative arrayを使用することはできません
+0

連想配列に 'MULTISET'を使用することはできません。 –

答えて

0

associative arraySQL 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; 
+0

ありがとう!グローバルスコープに関する問題(あなたは間違いなく)以外にも、(あなたのソリューションのように)数値コレクションの代わりにVARCHAR(私の元のコードのように)でインデックスされたグローバル連想配列を使用する方法はありますか? – serkelion

+0

いいえ、テーブルタイプのみ – Vecchiasignora

+0

@serkelion 12cから、テーブル仕様をパッケージ仕様で定義されている連想配列で使用することができます。 – 0xdb

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; 

希望します。

関連する問題