ヘッダーをスキップ
Oracle Databaseデータ・カートリッジ開発者ガイド
11gリリース1(11.1)
E05688-02
  目次
目次
索引
索引

戻る
戻る
次へ
次へ
 

3 オブジェクト型の定義

この章では、データ・カートリッジ用のスキーマから始まる例について説明します。オブジェクト型は、ドメイン・レベルの抽象化をデータベース内で取得可能にするという点で、データ・カートリッジを作成する上で重要です。

この章の内容は、次のとおりです。

オブジェクトとオブジェクト型

Oracle Object-Relational Database Management System(ORDBMS)では、オブジェクト型を使用して現実のエンティティをモデル化します。オブジェクト型は、エンティティの構造を反映した属性と、エンティティに対する操作を実装するメソッドを持ちます。属性の定義には、組込み型または他のオブジェクト型を使用します。メソッドとは、PL/SQLまたはCのような外部言語で記述され、データベースに格納されるファンクションまたはプロシージャです。

オブジェクト型の通常の用途は、データベースに格納されるデータの一部に構造を適用することです。たとえば、カートリッジでDataStreamというオブジェクト型を使用して、大量のデータをキャラクタLOB(ラージ・オブジェクトのデータ型)に格納できます。このオブジェクト型には、識別子、名前、日付などの属性があります。例3-1の文は、DataStreamデータ型を定義しています。

例3-1 DataStreamデータ型の定義方法

create or replace type DataStream as object (
   id integer,
   name varchar2(20),
   createdOn date,
   data clob,
   MEMBER FUNCTION DataStreamMin  return pls_integer,
   MEMBER FUNCTION DataStreamMax  return pls_integer,
   MAP MEMBER FUNCTION DataStreamToInt  return integer,
   PRAGMA restrict_references(DataStreamMin, WNDS, WNPS),
   PRAGMA restrict_references(DataStreamMax, WNDS, WNPS));

メソッドとは、オブジェクト型定義の一部で、オブジェクト型のデータの属性を操作できるプロシージャまたはファンクションのことです。この種のメソッドはメンバー・メソッドと呼ばれ、オブジェクト型の構成要素として指定するときにキーワードMEMBERを取ります。DataStream型の定義では、3つのメソッドが宣言されています。最初の2つ(DataStreamMinおよびDataStreamMax)は、キャラクタLOBに格納されているデータ・ストリーム内でそれぞれ最小値および最大値を計算します。

第3のメソッド(DataStreamToInt)はマップ・メソッドであり、データ・ストリームの型のインスタンス間の比較を制御します。


関連項目

マップ・メソッドの詳細は、「オブジェクトの比較」を参照してください。

プラグマ(コンパイラ・ディレクティブ)RESTRICT_REFERENCESは、セキュリティのために必要であり、以降の項で説明します。

型を宣言した後に、型本体を定義します。本体には、型のメソッドのコードが含まれています。例3-2に、DataStream型の型本体の定義を示します。この例では、メンバー・ファンクションのメソッド(DataStreamMinおよびDataStreamMax)とマップ・メソッド(DataStreamToInt)が定義されています。

例3-2 型本体の定義方法

CREATE OR REPLACE TYPE BODY DataStream IS
    MEMBER FUNCTION DataStreamMin return pls_integer is
      a pls_integer := DS_Package.ds_findmin(data);
      begin return a; end;
    MEMBER FUNCTION DataStreamMax return pls_integer is
      b pls_integer := DS_Package.ds_findmax(data);
      begin return b; end;
    MAP MEMBER FUNCTION DataStreamToInt return integer is
      c integer := id;
      begin return c; end;
end;

DataStreamMinおよびDataStreamMaxは、PL/SQLパッケージDS_Package内のコール・ルーチンです。これらのメソッドは計算集中型になりがちなため(CLOBに格納されている数値を処理して最小値と最大値を判別します)、外部プロシージャとして定義されてCで実装されます。外部ディスパッチは、PL/SQLパッケージDS_Packageを介して送られます。この種のパッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

第3のメソッド、DataStreamToIntはPL/SQLで実装されます。DataStreamに識別子(id)属性があるため、このメソッドは識別子属性の値を戻すことができます。ただし、ほとんどのマップ・メソッドはDataStreamToIntよりも複雑です。


関連項目


オブジェクト型へのオブジェクト識別子の割当て

CREATE TYPE文には、ユーザー指定のオブジェクト識別子(OID)を型定義に関連付けるオプションのキーワードOIDがあります。複数のデータベースで使用するオブジェクト型を作成する場合は、このキーワードを使用する必要があります。

型はそれぞれがOIDを持ちます。オブジェクト型を作成してもOIDを指定しなければ、OracleによりOIDが生成されて型に割り当てられます。Oracleでは、その型に関する操作に対して内部的にOIDが使用されます。エクスポート、インポートおよび分散問合せなどの操作で複数のデータベースにまたがって型のインスタンスを共有する予定の場合は、1つの型に同じOIDを使用することが重要です。


注意:

OIDを指定してCREATE TYPEを実行すると、OIDは型自体に割り当てられます。指定した型の列を含む表に作成される各行に、行固有のOIDが割り当てられます。

SpecialPersonという型を作成し、その型を表SpecialPersonTable1およびSpecialPersonTable2を含む2つの異なるデータベースでインスタンス化する必要があるとします。RDBMSは、SpecialPerson型が両方のインスタンスで同じ型であることを認識する必要があるため、両方のデータベースで同じOIDを使用してこの型を定義することになります。CREATE TYPEOIDを指定しなければ、RDBMSにより自動的に一意識別子が作成されます。オブジェクト型のOIDを指定する構文は、例3-3のとおりです。

例3-3 オブジェクト型に対するODIの指定方法

CREATE OR REPLACE TYPE type_name OID 'oid' AS OBJECT (attribute datatype [,...]);

例3-4では、SELECT文でOIDを生成し、CREATE TYPE文でOIDを使用してオブジェクト型mytypeを作成します。作成するオブジェクト型ごとに異なるOIDを生成する場合は、必ずSELECT文を使用してください。これは、各OIDが有効でグローバルに一意であることを保証する唯一の方法であるためです。

例3-4 OIDの割当ておよび使用方法

SQLPLUS> SELECT SYS_OP_GUID() FROM DUAL;
SYS_OP_GUID()
--------------------------------
19A57209ECB73F91E03400400B40BBE3
1 row selected.

SQLPLUS> CREATE TYPE mytype OID '19A57209ECB73F91E03400400B40BBE3'
     2> AS OBJECT (attrib1 NUMBER);
Statement processed.

コンストラクタ・メソッド

Oracleでは、定義するオブジェクト型ごとに暗黙的にコンストラクタ・メソッドが定義されます。コンストラクタ・メソッドの名前は、オブジェクト型と同じです。コンストラクタ・メソッドのパラメータはオブジェクト型のデータ属性と同じであり、オブジェクト型の属性定義と同じ順序で発生します。各オブジェクト型に対して定義できるコンストラクタ・メソッドは1つのみです。

例3-5で、システムがrational_typeという型を作成し、このオブジェクト型に対してコンストラクタ・メソッドを暗黙的に作成します。

例3-5 型の作成方法

CREATE TYPE rational_type (
     numerator integer,
     denominator integer);

rational_typeのオブジェクトをインスタンス化するときには、例3-6に示されているように、コンストラクタ・メソッドを起動します。

例3-6 オブジェクト型のインスタンス化の方法

CREATE TABLE some_table (
     c1 integer, c2 rational_type);
INSERT INTO some_table
     VALUES (42, rational_type(223, 71));

オブジェクトの比較

SQLでは、オブジェクトの比較操作が実行されます。一部の比較は、比較演算子(=、<、>、<>、<=、>=、!=)とBETWEENおよびIN述語を使用して明示的に実行されます。他の比較は、GROUP BYORDER BYDISTINCTおよびUNIQUE句のように暗黙的です。

オブジェクトの比較には、オブジェクト型の特殊なメンバー・ファンクションであるマップ・メソッドと順序付けメソッドを使用します。オブジェクト比較を実行するには、CREATE TYPEおよびCREATE TYPE BODY文でマップ・メソッドまたは順序付けメソッドを実装する必要があります。例3-7で、DataStream型に対する型本体はマップ・メンバー・ファンクションを実装します。

例3-7 メンバー・ファンクションの実装方法

MAP MEMBER FUNCTION DataStreamToInt return integer is
      c integer := id;
      begin return c; end;

マップ・メンバー・ファンクションのこの定義は、インスタンスを整数にマップするDataStream型のid属性の存在に依存しています。DataStream型のオブジェクト間で比較操作が必要になると、システムにより暗黙的にマップ・ファンクションDataStreamToInt()がコールされます。

オブジェクト型rational_typeには、DataStreamのような単純なid属性はありません。かわりに、マップ・メンバー・ファンクションは、例3-8で示されているように、複雑です。マップ・ファンクションは任意の組込み型を戻すことができるため、rational_typeは値またはREAL型を戻すことができます。

例3-8 単純なID属性なしでの型へのファンクションの実装方法

MAP MEMBER FUNCTION RationalToReal RETURN REAL IS
     BEGIN
         RETURN numerator/denominator;
     END;
...

オブジェクト型に対してマップ・ファンクションまたは順序付けファンクションを定義していない場合、サポートできるのは等価比較のみです。Oracle SQLでは、その型の属性がフィールドごとに比較されます。