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 を使うことによって、プロシージャやパッケージ内で完結できなくなってしまうのがちょっと残念ですね。