TABLE演算子と CAST演算子を使うと、SQLで VARRAY、ネストした表といったコレクションを要素ごとの行にばらし、表のように扱うことができます。
ネストした表の例
CREATE TYPE object_type IS OBJECT ( col1 VARCHAR2(100), col2 NUMBER(10) ) / CREATE TYPE object_table_type IS TABLE OF object_type / DECLARE object_table object_table_type; CURSOR cur IS SELECT * FROM TABLE(CAST(object_table AS object_table_type)); wk_rec cur%ROWTYPE; BEGIN object_table := object_table_type( object_type('A',1), object_type('B',2), object_type('C',3), object_type('D',4), object_type('E',5) ); OPEN cur; LOOP FETCH cur INTO wk_rec; EXIT WHEN cur%NOTFOUND; DBMS_OUTPUT.PUT_LINE(wk_rec.col1 || ',' || wk_rec.col2); END LOOP; CLOSE cur; END; /
OBJECT型のネストした表を定義し、各OBJECT型要素を行として取り出し、OBJECT型要素内の各属性を列として取り出します。
VARRAYの例
CREATE TYPE number_array_type IS VARRAY(5) OF NUMBER / DECLARE number_array number_array_type; CURSOR cur IS SELECT * FROM TABLE(CAST(number_array AS number_array_type)); wk_num NUMBER; BEGIN number_array := number_array_type(1,2,3,4,5); OPEN cur; LOOP FETCH cur INTO wk_num; EXIT WHEN cur%NOTFOUND; DBMS_OUTPUT.PUT_LINE(wk_num); END LOOP; CLOSE cur; END; /
VARRAYの各要素を行として取り出します。
(VARRAYの場合、列名は何になるんでしょう...?)
このようにしてコレクションの要素を抽出するプロセスのことを「コレクション・ネスト解除」と呼ぶそうです。
データベースに永続表として格納するような性質ではないけれども、プログラム内で表として扱いたい...そんな場面で重宝する機能です。
ただし、これが可能なのは使用するコレクション型をスキーマ・レベルで定義している(CREATE TYPEで定義している)場合のみのようです。
コレクション型をローカル・レベルで定義している(PL/SQLブロック内で定義している)場合は、以下のエラーが発生します。
PLS-00642: SQL文ではローカル・コレクション型は使用できません。
便利な機能だと思うのですが、CREATE TYPE を使うことによって、プロシージャやパッケージ内で完結できなくなってしまうのがちょっと残念ですね。