3 データ・カートリッジのオブジェクト型の定義

オブジェクト型は、ドメイン・レベルの抽象化をデータベース内で取得可能にするという点で、データ・カートリッジを作成する上で重要です。

3.1 データ・カートリッジのオブジェクトおよびオブジェクト型

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

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

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

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

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

関連項目:

3.1.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;

3.1.2 型本体の定義

例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;

3.2 データ・カートリッジのオブジェクト型へのオブジェクト識別子の割当て

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-4では、SELECT文によってOIDが生成され、CREATE TYPE文がそのOIDを使用して、mytypeという名前のオブジェクト型を作成します。作成する各オブジェクト型に対して異なるOIDを生成するには、必ずSELECT文を使用してください。この方法が、各OIDが有効であり、グローバルに一意であることを保証するための唯一の方法です。

3.2.1 データ・カートリッジのオブジェクト型に対するODIの指定

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

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

3.2.2 データ・カートリッジでの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.

3.3 データ・カートリッジのコンストラクタ・メソッド

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

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

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

3.3.1 型の作成

例3-5 型の作成

CREATE TYPE rational_type (
     numerator integer,
     denominator integer);

3.3.2 型オブジェクトのインスタンス化

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

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

3.4 データ・カートリッジでのオブジェクトの比較

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

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

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

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

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

3.4.1 メンバー・ファンクションの実装

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

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

3.4.2 単純なID属性のない型に対するファンクションの実装

例3-8 単純なID属性のない型に対するファンクションの実装

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