Plsql-object-oriented

提供:Dev Guides
移動先:案内検索

PL/SQL-オブジェクト指向

この章では、オブジェクト指向のPL/SQLについて説明します。 PL/SQLでは、オブジェクト型を定義できます。これにより、Oracleでオブジェクト指向データベースを設計できます。 オブジェクト型を使用すると、複合型を作成できます。 オブジェクトを使用すると、特定のデータ構造とそれを操作するためのメソッドを持つ実世界のオブジェクトを実装できます。 オブジェクトには属性とメソッドがあります。 属性はオブジェクトのプロパティであり、オブジェクトの状態を保存するために使用されます。メソッドはその動作をモデル化するために使用されます。

オブジェクトは、CREATE [OR REPLACE] TYPEステートメントを使用して作成されます。 以下は、いくつかの属性で構成される単純な address オブジェクトを作成する例です-

CREATE OR REPLACE TYPE address AS OBJECT
(house_no varchar2(10),
 street varchar2(30),
 city varchar2(20),
 state varchar2(10),
 pincode varchar2(10)
);
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

Type created.

もう1つのオブジェクト customer を作成して、オブジェクト指向の感覚を持たせるために attributesmethods を一緒にラップします。

CREATE OR REPLACE TYPE customer AS OBJECT
(code number(5),
 name varchar2(30),
 contact_no varchar2(12),
 addr address,
 member procedure display
);
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

Type created.

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

オブジェクトタイプを定義すると、オブジェクトの青写真が提供されます。 このオブジェクトを使用するには、このオブジェクトのインスタンスを作成する必要があります。 次のようにインスタンス名と*アクセス演算子(。)*を使用して、オブジェクトの属性とメソッドにアクセスできます-

DECLARE
   residence address;
BEGIN
   residence := address('103A', 'M.G.Road', 'Jaipur', 'Rajasthan','201301');
   dbms_output.put_line('House No: '|| residence.house_no);
   dbms_output.put_line('Street: '|| residence.street);
   dbms_output.put_line('City: '|| residence.city);
   dbms_output.put_line('State: '|| residence.state);
   dbms_output.put_line('Pincode: '|| residence.pincode);
END;
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

House No: 103A
Street: M.G.Road
City: Jaipur
State: Rajasthan
Pincode: 201301

PL/SQL procedure successfully completed.

メンバーメソッド

  • メンバーメソッド*は、オブジェクトの*属性*を操作するために使用されます。 オブジェクト型を宣言しながら、メンバーメソッドの宣言を提供します。 オブジェクト本体は、メンバーメソッドのコードを定義します。 オブジェクト本体は、CREATE TYPE BODYステートメントを使用して作成されます。
  • コンストラクタ*は、値として新しいオブジェクトを返す関数です。 すべてのオブジェクトには、システム定義のコンストラクターメソッドがあります。 コンストラクターの名前はオブジェクトタイプと同じです。 たとえば-
residence := address('103A', 'M.G.Road', 'Jaipur', 'Rajasthan','201301');
  • 比較方法*はオブジェクトの比較に使用されます。 オブジェクトを比較するには2つの方法があります-

マップ方式

  • Mapメソッド*は、値が属性の値に依存するように実装された関数です。 たとえば、顧客オブジェクトの場合、2人の顧客の顧客コードが同じであれば、両方の顧客が同じになる可能性があります。 したがって、これら2つのオブジェクト間の関係は、コードの値に依存します。

注文方法

  • Orderメソッド*は、2つのオブジェクトを比較するためのいくつかの内部ロジックを実装します。 たとえば、長方形オブジェクトの場合、長方形の両側が大きい場合、長方形は別の長方形よりも大きくなります。

Mapメソッドを使用する

次の長方形オブジェクトを使用して上記の概念を理解してみましょう-

CREATE OR REPLACE TYPE rectangle AS OBJECT
(length number,
 width number,
 member function enlarge( inc number) return rectangle,
 member procedure display,
 map member function measure return number
);
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

Type created.

型本体の作成-

CREATE OR REPLACE TYPE BODY rectangle AS
   MEMBER FUNCTION enlarge(inc number) return rectangle IS
   BEGIN
      return rectangle(self.length + inc, self.width + inc);
   END enlarge;
   MEMBER PROCEDURE display IS
   BEGIN
      dbms_output.put_line('Length: '|| length);
      dbms_output.put_line('Width: '|| width);
   END display;
   MAP MEMBER FUNCTION measure return number IS
   BEGIN
      return (sqrt(length*length + width*width));
   END measure;
END;
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

Type body created.

今長方形オブジェクトとそのメンバー関数を使用して-

DECLARE
   r1 rectangle;
   r2 rectangle;
   r3 rectangle;
   inc_factor number := 5;
BEGIN
   r1 := rectangle(3, 4);
   r2 := rectangle(5, 7);
   r3 := r1.enlarge(inc_factor);
   r3.display;
   IF (r1 > r2) THEN -- calling measure function
      r1.display;
   ELSE
      r2.display;
   END IF;
END;
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

Length: 8
Width: 9
Length: 5
Width: 7

PL/SQL procedure successfully completed.

Orderメソッドを使用する

現在、注文方法を使用して*同じ効果を達成できます*。 順序メソッドを使用して長方形オブジェクトを再作成しましょう-

CREATE OR REPLACE TYPE rectangle AS OBJECT
(length number,
 width number,
 member procedure display,
 order member function measure(r rectangle) return number
);
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

Type created.

型本体の作成-

CREATE OR REPLACE TYPE BODY rectangle AS
   MEMBER PROCEDURE display IS
   BEGIN
      dbms_output.put_line('Length: '|| length);
      dbms_output.put_line('Width: '|| width);
   END display;
   ORDER MEMBER FUNCTION measure(r rectangle) return number IS
   BEGIN
      IF(sqrt(self.length*self.length + self.width*self.width)>
         sqrt(r.length*r.length + r.width*r.width)) then
         return(1);
      ELSE
         return(-1);
      END IF;
   END measure;
END;
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

Type body created.

長方形オブジェクトとそのメンバー関数を使用して-

DECLARE
   r1 rectangle;
   r2 rectangle;
BEGIN
   r1 := rectangle(23, 44);
   r2 := rectangle(15, 17);
   r1.display;
   r2.display;
   IF (r1 > r2) THEN -- calling measure function
      r1.display;
   ELSE
      r2.display;
   END IF;
END;
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

Length: 23
Width: 44
Length: 15
Width: 17
Length: 23
Width: 44

PL/SQL procedure successfully completed.

PL/SQLオブジェクトの継承

PL/SQLでは、既存のベースオブジェクトからオブジェクトを作成できます。 継承を実装するには、ベースオブジェクトを NOT FINAL として宣言する必要があります。 デフォルトは FINAL です。

次のプログラムは、PL/SQLオブジェクトの継承を示しています。 TableTop という名前の別のオブジェクトを作成してみましょう。これはRectangleオブジェクトから継承されます。 このために、我々はベース_rectangle_オブジェクトを作成する必要があります-

CREATE OR REPLACE TYPE rectangle AS OBJECT
(length number,
 width number,
 member function enlarge( inc number) return rectangle,
 NOT FINAL member procedure display) NOT FINAL
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

Type created.

基本型本体の作成-

CREATE OR REPLACE TYPE BODY rectangle AS
   MEMBER FUNCTION enlarge(inc number) return rectangle IS
   BEGIN
      return rectangle(self.length + inc, self.width + inc);
   END enlarge;
   MEMBER PROCEDURE display IS
   BEGIN
      dbms_output.put_line('Length: '|| length);
      dbms_output.put_line('Width: '|| width);
   END display;
END;
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

Type body created.

子オブジェクト_tabletop_の作成-

CREATE OR REPLACE TYPE tabletop UNDER rectangle
(
   material varchar2(20),
   OVERRIDING member procedure display
)
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

Type created.

子オブジェクト_tabletop_のタイプボディの作成

CREATE OR REPLACE TYPE BODY tabletop AS
OVERRIDING MEMBER PROCEDURE display IS
BEGIN
   dbms_output.put_line('Length: '|| length);
   dbms_output.put_line('Width: '|| width);
   dbms_output.put_line('Material: '|| material);
END display;
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

Type body created.

_tabletop_オブジェクトとそのメンバー関数を使用して-

DECLARE
   t1 tabletop;
   t2 tabletop;
BEGIN
   t1:= tabletop(20, 10, 'Wood');
   t2 := tabletop(50, 30, 'Steel');
   t1.display;
   t2.display;
END;
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

Length: 20
Width: 10
Material: Wood
Length: 50
Width: 30
Material: Steel

PL/SQL procedure successfully completed.

PL/SQLの抽象オブジェクト

*NOT INSTANTIABLE* 句を使用すると、抽象オブジェクトを宣言できます。 抽象オブジェクトをそのまま使用することはできません。そのようなオブジェクトのサブタイプまたは子タイプを作成して、その機能を使用する必要があります。

例えば、

CREATE OR REPLACE TYPE rectangle AS OBJECT
(length number,
 width number,
 NOT INSTANTIABLE NOT FINAL MEMBER PROCEDURE display)
 NOT INSTANTIABLE NOT FINAL
/

上記のコードがSQLプロンプトで実行されると、次の結果が生成されます-

Type created.