5.2 マルチレベル・コレクション型

マルチレベル・コレクション型とは、要素自体が直接的または間接的に別のコレクション型であるコレクション型です。

使用可能なマルチレベル・コレクション型は、次のとおりです。

  • ネストした表型のネストした表

  • VARRAY型のネストした表

  • ネストした表型のVARRAY

  • VARRAY型のVARRAY

  • ネストした表またはVARRAY型である属性を持つユーザー定義型のネストした表またはVARRAY

シングルレベル・コレクション型と同様に、マルチレベル・コレクション型には次の特徴があります。

  • リレーショナル表の列として、またはオブジェクト表のオブジェクト属性とともに使用できます。

  • 代入では、ソースとターゲットにいずれも同じデータ型が宣言されている必要があります。

内容は次のとおりです。

5.2.1 マルチレベル・コレクション型のネストした表の記憶表

ネストした表のマルチレベルのネストした表コレクションを使用するには、ネストした表の記憶域の句を指定する必要があります。

「ネストした表の要素の格納」で説明したように、ネストした表型の列またはオブジェクト表属性には、ネストした表すべての行を格納するための記憶表が必要になります。

ネストした表のマルチレベルのネストした表コレクションの場合、ネストした表の内側のセットと外側のセットのいずれについても、ネストした表の記憶域の句(STORE AS)を指定する必要があります。コレクションで保持するネストした表のレベルと同数のネストした表の記憶域句が必要です。

ネストした表のどの記憶表にも、NESTED_TABLE_IDで参照可能な列が含まれており、その列では、記憶表内の行を親表内の関連する行と対応付けます。それ自体がネストした表である親表には、システムから提供されたID列が2つあります。

  • システムから提供された、NESTED_TABLE_IDにより参照可能なID列。これにより、その行が親表の行に再び関連付けられます。

  • システムから提供された、ネストした表の子の中のNESTED_TABLE_ID列により隠蔽および参照されるID列。

NESTED_TABLE_ID列とともに主キーを指定しない場合、パフォーマンスの向上のためにNESTED_TABLE_ID列のBツリー索引が自動的に作成されます。

関連項目:

内容は次のとおりです。

5.2.1.1 マルチレベルのネストした表の記憶域の作成

ネストした表のネストした表を作成できます。

例5-10では、ネストした表のネストした表であるマルチレベル・コレクション型nt_country_typを作成します。この例では、それぞれの地域に国のネストした表のコレクションが存在し、それぞれの国にその所在地のネストした表のコレクションが存在する企業の地域体系をモデル化します。この例では、Oracle HRサンプル・スキーマのregionscountriesおよびlocations表が必要です。

例5-10のSQL文は、型がマルチレベル・コレクション(nt_country_typ)である列countriesが含まれる表region_tabを作成します。このマルチレベル・コレクションは、ネストした表属性locationsを持つオブジェクト型のネストした表です。外側のネストした表countriesと内側のネストした表locationsに対し、別々のネストした表句が用意されています。

例5-10では、このネストした表はオブジェクトの名前付き属性になっているため、内側のネストした表locationsを名前で参照できます。ただし、内側のネストした表がオブジェクトの属性でない場合には、名前はありません。この場合には、キーワードCOLUMN_VALUEが用意されています。例5-11を参照

例5-10 マルチレベルのネストした表の記憶域

-- Requires the HR sample schema
CREATE TYPE location_typ AS OBJECT (
  location_id      NUMBER(4),
  street_address   VARCHAR2(40),
  postal_code      VARCHAR2(12),
  city             VARCHAR2(30),
  state_province   VARCHAR2(25));
/

CREATE TYPE nt_location_typ AS TABLE OF location_typ;  -- nested table type
/

CREATE TYPE country_typ AS OBJECT (
  country_id     CHAR(2),
  country_name   VARCHAR2(40),
  locations      nt_location_typ); -- inner nested table
/

CREATE TYPE nt_country_typ AS TABLE OF country_typ;  -- multilevel collection type
/

CREATE TABLE region_tab (
  region_id     NUMBER,
  region_name   VARCHAR2(25),
  countries     nt_country_typ) -- outer nested table
  NESTED TABLE countries STORE AS nt_countries_tab
   (NESTED TABLE locations STORE AS nt_locations_tab);

関連項目:

サンプル・スキーマの使用方法の詳細は、『Oracle Databaseサンプル・スキーマ』を参照してください。

5.2.1.2 COLUMN_VALUEキーワードを使用したマルチレベルのネストした表の記憶域の作成

内側のネストした表に対して名前のかわりにキーワードCOLUMN_VALUEを使用できます。

例5-11では、内側のネストした表には名前が付いておらず、キーワードCOLUMN_VALUEで表されています。

例5-11 COLUMN_VALUEキーワードを使用したマルチレベルのネストした表の記憶域

CREATE TYPE inner_table AS TABLE OF NUMBER;
/
CREATE TYPE outer_table AS TABLE OF inner_table;
/
CREATE TABLE tab1 (
  col1 NUMBER,  -- inner nested table, unnamed
  col2 outer_table)
NESTED TABLE col2 STORE AS col2_ntab
  (NESTED TABLE COLUMN_VALUE STORE AS cv_ntab);

5.2.1.3 ネストした表の記憶域の物理属性の指定

ネストした表の記憶域の物理属性を指定できます。

例5-12に、ネストした表の句の中で記憶表の物理属性を指定する方法を示します。

NESTED_TABLE_IDを使用して主キーを1列目として指定し、表の索引構成を行うと、同じ親である行に属するネストした表の行すべてが、物理的にクラスタ化され、さらに効率的にアクセスできるようになります。例5-12では、ネストした表に1列目がNESTED_TABLE_IDになっている主キーがあります。この列には、記憶表の行が関連付けられた親表内の行のIDが入っています。

例5-12 ネストした表の記憶域の物理属性の指定

-- Requires Ex. 5-10
-- drop the following if you have previously created it
DROP TABLE region_tab FORCE;

CREATE TABLE region_tab (
  region_id     NUMBER,
  region_name   VARCHAR2(25),
  countries     nt_country_typ)
  NESTED TABLE countries STORE AS nt_countries_tab (
   (PRIMARY KEY (NESTED_TABLE_ID, country_id))
      NESTED TABLE locations STORE AS nt_locations_tab);

5.2.2 マルチレベル・コレクションのVARRAY記憶域

マルチレベルVARRAYの格納方法は、VARRAYが複数個あるVARRAYの1つである場合と、ネストした表の1つのVARRAYである場合とでは異なります。

  • 複数個あるVARRAYの中の1つのVARRAYの場合、そのサイズが約4000バイト以上の場合、またはLOB記憶域が明示的に指定されている場合を除き、VARRAY全体がインラインで行に格納されます。

  • ネストした表のVARRAYの場合、VARRAY全体がLOBに格納され、LOBロケータのみが行に格納されます。VARRAYのネストした表要素と関連付けられた記憶表は、存在しません。

VARRAYについては、LOB記憶域を明示的に指定できます。

関連項目:

5.2.3 VARRAY型のVARRAYに対するLOB記憶域の指定

VARRAY型のVARRAYに対してLOB記憶域を明示的に指定できます。

例5-13に、VARRAY型のVARRAYに対して指定された明示的なLOB記憶域を示します。

例5-13 VARRAY型のVARRAYに使用するLOB記憶域の指定

-- Requires Ex. 5-8, drop following if created

DROP TYPE email_varray_typ FORCE;
CREATE TYPE email_list_typ2 AS OBJECT (
    section_no   NUMBER, 
    emails       email_list_arr);
/

CREATE TYPE email_varray_typ AS VARRAY(5) OF email_list_typ2;
/

CREATE TABLE dept_email_list2 (
  dept_no NUMBER, 
  email_addrs email_varray_typ)
  VARRAY email_addrs STORE AS LOB dept_emails_lob2;

5.2.4 VARRAYのネストした表に対するLOB記憶域の指定

VARRAY要素のネストした表に対してLOB記憶域を明示的に指定できます。

例5-14では、VARRAYとともにCOLUMN_VALUEキーワードを使用しています。このキーワードの説明、およびこれをネストした表に対して使用する方法は、例5-11を参照してください。

例5-14 VARRAYのネストした表に使用するLOB記憶域の指定

-- drop the following types if you have created them
DROP TYPE email_list_typ FORCE;
DROP TABLE dept_email_list FORCE;
DROP TYPE email_list_arr FORCE;

CREATE TYPE email_list_arr AS VARRAY(10) OF VARCHAR2(80);
/

CREATE TYPE email_list_typ AS TABLE OF email_list_arr;
/

CREATE TABLE dept_email_list (
  dept_no NUMBER, 
  email_addrs email_list_typ)
  NESTED TABLE email_addrs STORE AS email_addrs_nt
  (
VARRAY COLUMN_VALUE STORE AS LOB
 dept_emails_lob);

5.2.5 マルチレベル・コレクションのコンストラクタ

マルチレベル・コレクション型は、シングルレベル・コレクションやその他のオブジェクト型と同様、個々の型のコンストラクタをコールして作成します。

マルチレベル・コレクション型のコンストラクタはシステム定義ファンクションの1つで、型と同じ名前を持ち、その型の新しいインスタンスを戻します。コンストラクタ・パラメータは、オブジェクト型の属性の名前と型を持ちます。

例5-15に、マルチレベル・コレクション型nt_country_typのコンストラクタ・コールを示します。nt_country_typコンストラクタがcountry_typコンストラクタをコールし、country_typコンストラクタがnt_location_typコンストラクタをコールし、nt_location_typコンストラクタがlocation_typコンストラクタをコールします。

注意:

nt_country_typは、別のネストした表が属性として含まれるネストした表であるため、マルチレベル・コレクションです。

例5-15 マルチレベル・コレクションのコンストラクタの使用

-- Requires 5-10 and HR sample schema
INSERT INTO region_tab 
VALUES(1, 'Europe', nt_country_typ( 
  country_typ( 'IT', 'Italy', nt_location_typ (
    location_typ(1000, '1297 Via Cola di Rie','00989','Roma', ''),
    location_typ(1100, '93091 Calle della Testa','10934','Venice','') ) 
    ),
  country_typ( 'CH', 'Switzerland', nt_location_typ (
    location_typ(2900, '20 Rue des Corps-Saints', '1730', 'Geneva', 'Geneve'),
    location_typ(3000, 'Murtenstrasse 921', '3095', 'Bern', 'BE') ) 
    ),
  country_typ( 'UK', 'United Kingdom', nt_location_typ (
    location_typ(2400, '8204 Arthur St', '', 'London', 'London'),
    location_typ(2500, 'Magdalen Centre, The Oxford Science Park', 'OX9 9ZB',
                 'Oxford', 'Oxford'),
    location_typ(2600, '9702 Chester Road', '09629850293', 'Stretford',
                 'Manchester') )
      ) 
  )
);