日本語PDF

14.13 CREATE TYPE文

CREATE TYPE文は、型の名前、属性、メソッドおよびその他のプロパティを指定します。

CREATE TYPE文は、次のいずれかの仕様を作成するか、または置き換えます。

  • 抽象データ型(ADT)

  • スタンドアロン型の可変配列(VARRAY)型

  • スタンドアロン型のネストした表型

  • 不完全なオブジェクト型

    不完全型とは、フォワード型定義によって作成される型です。このオブジェクト型には名前はありますが、属性およびメソッドがないために不完全と呼ばれます。他の型からの参照が可能なため、互いに参照する型を定義できます。ただし、不完全オブジェクト型を使用して表やオブジェクト列またはネストした表型の列を作成する場合は、型を完全に指定しておく必要があります。

CREATE TYPE BODY文には、その型を実装するメソッドに対するコードが含まれます。

ノート:

  • 仕様部で属性のみを宣言し、メソッドは宣言しない型を作成する場合、型本体を指定する必要はありません。

  • CREATE TYPE文で作成するスタンドアロン・コレクション型は、PL/SQLブロックまたはパッケージでTYPEキーワードを使用して定義するコレクション型とは異なります。後者の詳細は、「コレクション変数の宣言」を参照してください。

  • CREATE TYPE文を使用した場合、ネストした表型およびVARRAY型は作成できますが、結合配列は作成できません。PL/SQLブロックまたはパッケージでは、3つすべてのコレクション型を定義できます。

ここでのトピック

前提条件

自分のスキーマ内に型を作成するには、CREATE TYPEシステム権限が必要です。他のユーザーのスキーマ内に型を作成する場合は、CREATE ANY TYPEシステム権限が必要です。これらの権限は、明示的に取得することもロールを介して取得することもできます。

サブタイプを作成するには、UNDER ANY TYPEシステム権限またはスーパータイプに対するUNDERオブジェクト権限が必要です。

型の所有者には、型定義内で参照する他のすべての型にアクセスするためのEXECUTEオブジェクト権限、またはEXECUTE ANY TYPEシステム権限が必要です。所有者は、これらの権限をロールを介して取得することはできません。

型の所有者が、型にアクセスする権限を他のユーザーに付与する場合、所有者には、参照型に対するGRANT OPTION付きのEXECUTEオブジェクト権限、またはADMIN OPTION付きのEXECUTE ANY TYPEシステム権限が必要です。これらの権限がない場合、型の所有者は、型にアクセスする権限を他のユーザーに付与できません。

構文

create_type ::=

セマンティクス

create_type

OR REPLACE

型が存在する場合は、型を再作成し、再コンパイルします。

再定義する前の型に対する権限を付与されていたユーザーは、権限を再付与される必要なく、型にアクセスできます。

ファンクション索引が型に依存している場合、データベースによって索引にDISABLEDのマークが付けられます。

[ EDITIONABLE | NONEDITIONABLE ]

schemaでスキーマ・オブジェクト・タイプTYPEに対してエディションが有効になっている場合に、型がエディション・オブジェクトまたは非エディション・オブジェクトのどちらになるかを指定します。デフォルト: EDITIONABLE。エディション・オブジェクトと非エディション・オブジェクトの詳細は、『Oracle Database開発ガイド』を参照してください。

plsql_type_source

schema

型が含まれているスキーマの名前。デフォルト: 自分のスキーマ。

type_name

ADT、ネストした表型またはVARRAY型の名前。

型の作成時にコンパイル・エラーが発生した場合は、エラーが戻されます。関連付けられているコンパイラ・エラー・メッセージは、SQL*PlusコマンドSHOW ERRORSを使用して確認できます。

作成した各ユーザー定義型に対して、データベースによって暗黙的にコンストラクタ・メソッドが定義されます。コンストラクタは、型の値のインスタンスを構成するためにSQL文またはPL/SQLコードで使用されるシステム提供のプロシージャです。コンストラクタ・メソッドの名前は、ユーザー定義型の名前です。また、constructor_spec構文を使用して、ユーザー定義コンストラクタを作成することもできます。

ADTのコンストラクタ・メソッドのパラメータは、ADTのデータ属性です。また、そのADT用の属性定義と同じ順序で定義されます。ネストした表またはVARRAYコンストラクタのパラメータは、ネストした表またはVARRAYの要素です。

FORCE

type_nameが存在し、型依存性はあり、表依存性はない場合は、FORCEによって文の型が置き換えられます。(type_nameに表依存性がある場合は、FORCEの有無にかかわらず文は失敗します。)

ノート:

t1に型t2との依存性があり、型t2に表依存性がある場合は、型t1にも表依存性があります。

OID 'object_identifier'

複数のデータベースで同一オブジェクトの型の等価を設定します。この句の詳細は、『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』を参照してください。

object_base_type_def

スキーマ・レベルのADTを作成します。このようなADTは、ルートADTと呼ばれる場合があります。

IS | AS

ADTの作成時には、キーワードISまたはASが必要です。

関連項目:

例14-23

object_subtype_def

既存の型のサブタイプを作成します。

UNDER supertype

既存のスーパータイプは、ADTである必要があります。この文で作成したサブタイプは、スーパータイプのプロパティを継承します。サブタイプではプロパティの一部をオーバーライドするか、またはプロパティを追加して、スーパータイプと区別する必要があります。

関連項目:

例14-24および例14-25

attribute

ADT属性の名前。ADT属性は、ADTの構造を形成する、名前および型指定子を持つデータ項目です。各ADTには、1つ以上の属性を指定する必要があります。名前はそのADT内で一意である必要がありますが、他のADT内では使用できます。

サブタイプを作成する場合、連鎖するスーパータイプで宣言されている属性名またはメソッド名と同じ属性名を指定することはできません。

datatype

ADT属性のデータ型。このデータ型は、データベースに格納されている必要があります(つまり、事前定義のデータ型またはユーザー定義のスタンドアロン・コレクション型のいずれかになります)。

datatypeの制限

  • 属性にNOT NULL制約を課すことはできません。

  • ROWID型、LONG型またはLONG RAW型の属性は指定できません。

  • UROWIDというデータ型は、ADTには指定できません。

  • REF型のオブジェクトを指定する場合、ターゲット・オブジェクトにはオブジェクト識別子が必要です。

  • ネストした表または表のVARRAY列として使用するためのコレクション型を作成する場合、ANYTYPE型、ANYDATA型またはANYDATASET型の属性を指定することはできません。

object_type_def

ADTを作成します。データ構造を形成する変数は、属性と呼ばれます。ADTの動作を定義するメンバー・サブプログラムは、メソッドと呼ばれます。

OBJECT

キーワードOBJECTは必要です。

[NOT]FINAL、[NOT]INSTANTIABLE、[NOT]PERSISTABLE

これらの句を構文のスキーマ・レベルで指定すると、型の継承する属性を指定できます。

[NOT] FINAL

[NOT] FINAL句を使用すると、この型のサブタイプをさらに作成できるようにするかどうかを指定できます。

  • (デフォルト)この型に対してサブタイプをさらに作成できないようにする場合は、FINALを指定します。

  • この型に対してサブタイプをさらに作成できるようにする場合は、NOT FINALを指定します。

[NOT] INSTANTIABLE

[NOT] INSTANTIABLE句を使用すると、この型のオブジェクト・インスタンスを作成できるかどうかを構成できます。

  • (デフォルト)この型のオブジェクト・インスタンスを構成できる場合は、INSTANTIABLEを指定します。

  • このADTに対してデフォルトまたはユーザー定義のコンストラクタが存在しない場合は、NOT INSTANTIABLEを指定します。インスタンス化ができないメソッドを持つ型、および継承された属性またはこの句で指定された属性を持たない型には、これらのキーワードを指定する必要があります。

[NOT] PERSISTABLE

[NOT] PERSISTABLE句を使用して、このオブジェクト型のインスタンスが存続可能であるかどうかを指定します。

表に格納できるのはPERSISTABLE型のみです。

  • (デフォルト)オブジェクト型のすべての属性が存続可能である場合、PERSISTABLEを指定できます。存続不可の属性を持つ存続可能オブジェクト型は作成できません。

  • オブジェクト型の属性が存続可能または存続不可の場合、NOT PERSISTABLEを指定できます。

[NOT] PERSISTABLEの制限

サブタイプ定義に[NOT] PERSISTABLE句は指定できません。サブタイプの存続可否プロパティはスーパータイプから継承されます。

varray_type_spec

それぞれが同じデータ型を持つ要素の順序付け集合として型を作成します。

varray_type_specの制限

PL/SQLまたはビュー問合せなど、手順上の目的でXMLTypeまたはLOB型のVARRAY型を作成できます。ただし、そのようなVARRAY型のデータベースへの格納はサポートされていないため、そのようなVARRAY型のオブジェクト表または列は作成できません。

関連項目:

例14-26

[NOT] PERSISTABLE

( datatype [NOT NULL] )

PERSISTABLEが指定されている場合、datatype [NOT NULL]句の前後にはカッコが必要です。PERSISTABLEが指定されていない場合、カッコの指定は任意です。

[NOT] PERSISTABLE句を使用して、このコレクション型(VARRAYまたはネストされた表)のインスタンスが存続可能であるかどうかを指定します。
  • (デフォルト)コレクションの要素の型が存続可能である場合のみ、コレクションをPERSISTABLEにすることができます。存続不可の要素型を持つ存続可能コレクション型は作成できません。

  • 存続不可の要素型がコレクションに1つでも含まれている場合は、NOT PERSISTABLEを指定します。NOT PERSISTABLEは、要素の型が存続可能であるかどうかに関係なくすべてのコレクションに指定できます。

nested_table_type_spec

datatype型で名前付きのネストした表を作成します。

[NOT] PERSISTABLE

VARRAYと同様、[NOT] PERSISTABLEを参照してください。

関連項目:

例14-23 ADTの例

この例は、サンプルの注文入力スキーマ(oe)用にサンプルのcustomer_typ型を作成する方法を示しています。テスト・データベースでこの例を複製できるように、表に仮定の名前が指定されています。

CREATE TYPE customer_typ_demo AS OBJECT
    ( customer_id        NUMBER(6)
    , cust_first_name    VARCHAR2(20)
    , cust_last_name     VARCHAR2(20)
    , cust_address       CUST_ADDRESS_TYP
    , phone_numbers      PHONE_LIST_TYP
    , nls_language       VARCHAR2(3)
    , nls_territory      VARCHAR2(30)
    , credit_limit       NUMBER(9,2)
    , cust_email         VARCHAR2(30)
    , cust_orders        ORDER_LIST_TYP
    ) ;

次の例では、CREATE TYPE BODY文で実装されるメンバー・ファンクションprodを持つdata_typ1 ADTを作成します。

CREATE TYPE data_typ1 AS OBJECT 
   ( year NUMBER, 
     MEMBER FUNCTION prod(invent NUMBER) RETURN NUMBER 
   ); 
/
 
CREATE TYPE BODY data_typ1 IS   
      MEMBER FUNCTION prod (invent NUMBER) RETURN NUMBER IS 
         BEGIN 
             RETURN (year + invent);
         END; 
      END; 

例14-24 サブタイプの作成

この文は、サンプル・スキーマoeにサブタイプcorporate_customer_typを作成する方法を示しています。

前述の例で作成したスーパータイプcustomer_typに基づき、account_mgr_id属性を追加しています。テスト・データベースでこの例を複製できるように、表に仮定の名前が指定されています。

CREATE TYPE corporate_customer_typ_demo UNDER customer_typ
    ( account_mgr_id     NUMBER(6)
    );

例14-25 型階層の作成

これらの文により、型階層が作成されます。

employee_t型は、person_t型からnameおよびssn属性を継承し、department_idおよびsalary属性を追加しています。part_time_emp_t型は、employee_tおよび(employee_tを介して)person_tからすべての属性を継承し、num_hrs属性を追加しています。part_time_emp_tはデフォルトで最終型であるため、そのサブタイプを作成できません。

CREATE TYPE person_t AS OBJECT (name VARCHAR2(100), ssn NUMBER) 
   NOT FINAL;

CREATE TYPE employee_t UNDER person_t 
   (department_id NUMBER, salary NUMBER) NOT FINAL;

CREATE TYPE part_time_emp_t UNDER employee_t (num_hrs NUMBER);

この型階層を使用して、置換可能な表および置換可能な列を含む表を作成できます。

例14-26 VARRAY型の作成

この文は、サンプル・スキーマoeに、5つの要素を含むVARRAYphone_list_typを作成する方法を示しています。

テスト・データベースでこの例を複製できるように、表に仮定の名前が指定されています。

CREATE TYPE phone_list_typ_demo AS VARRAY(5) OF VARCHAR2(25);

例14-27 ネストした表型の作成

サンプル・スキーマpmからのこの例は、textdoc_typ型の表型textdoc_tabを作成します。

CREATE TYPE textdoc_typ AS OBJECT
    ( document_typ      VARCHAR2(32)
    , formatted_doc     BLOB
    ) ;

CREATE TYPE textdoc_tab AS TABLE OF textdoc_typ;

例14-28 VARRAYを含むネストした表型の作成

マルチレベル・コレクションのこの例は、サンプルの表oe.customersのバリエーションです。

この例では、cust_addressオブジェクト列は、VARRAY列phone_list_typが埋め込まれたネストした表の列になります。このphone_list_typ_demo型は、「例14-26」で作成された型です。

CREATE TYPE cust_address_typ2 AS OBJECT
       ( street_address     VARCHAR2(40)
       , postal_code        VARCHAR2(10)
       , city               VARCHAR2(30)
       , state_province     VARCHAR2(10)
       , country_id         CHAR(2)
       , phone              phone_list_typ_demo
       );

CREATE TYPE cust_nt_address_typ
   AS TABLE OF cust_address_typ2;

例14-29 コンストラクタの例

この例では、システム定義のコンストラクタを起動して、demo_typオブジェクトを構成し、構成したオブジェクトをdemo_tab表に挿入します。

CREATE TYPE demo_typ1 AS OBJECT (a1 NUMBER, a2 NUMBER);

CREATE TABLE demo_tab1 (b1 NUMBER, b2 demo_typ1);

INSERT INTO demo_tab1 VALUES (1, demo_typ1(2,3));

例14-30 メンバー・メソッドの作成

この例は、メソッド・コンストラクタcol.get_squareを起動します。

まず、型を作成します。

CREATE TYPE demo_typ2 AS OBJECT (a1 NUMBER, 
   MEMBER FUNCTION get_square RETURN NUMBER); 

次に、ADT列を持つ表を作成し、その表にデータを挿入します。

CREATE TABLE demo_tab2(col demo_typ2); 

INSERT INTO demo_tab2 VALUES (demo_typ2(2));

メンバー・ファンクションを定義する型本体を作成し、メンバー・メソッドを起動します。

CREATE TYPE BODY demo_typ2 IS
   MEMBER FUNCTION get_square
   RETURN NUMBER
   IS x NUMBER;
   BEGIN
      SELECT c.col.a1*c.col.a1 INTO x
      FROM demo_tab2 c;
      RETURN (x);
   END;
END;
 
SELECT t.col.get_square() FROM demo_tab2 t;

T.COL.GET_SQUARE()
------------------
                 4

ファンクションとは異なり、メソッドを起動する場合は、メソッドが他に引数を取らない場合でもカッコが必要です。

例14-31 静的メソッドの作成

この例は、employee_t型の定義を変更し、変更した定義をconstruct_empファンクションと関連付けます。

この例では、最初にADT department_tを作成し、次にdepartment_t型の属性を含むADT employee_tを作成します。

CREATE OR REPLACE TYPE department_t AS OBJECT (
   deptno number(10),
   dname CHAR(30));

CREATE OR REPLACE TYPE employee_t AS OBJECT(
   empid RAW(16),
   ename CHAR(31),
   dept REF department_t,
      STATIC function construct_emp
      (name VARCHAR2, dept REF department_t)
      RETURN employee_t
);

この文には、次の型本体の文が必要です。

CREATE OR REPLACE TYPE BODY employee_t IS
   STATIC FUNCTION construct_emp
   (name varchar2, dept REF department_t)
   RETURN employee_t IS
      BEGIN
         return employee_t(SYS_GUID(),name,dept);
      END;
END;

次に、オブジェクト表を作成し、表に挿入します。

CREATE TABLE emptab OF employee_t;
INSERT INTO emptab
   VALUES (employee_t.construct_emp('John Smith', NULL));

関連トピック

この章:

他の章:

その他のドキュメント: