天天看點

PL/SQL面向對象

PL/SQL允許定義一個對象類型,這有助于在Oracle的資料庫中設計的面向對象。對象類型可以包裝複合類型。使用對象允許實作資料的具體結構現實世界中的對象和方法操作它。對象有屬性和方法。屬性是一個對象的屬性,并用于存儲對象的狀态;和方法被用于模拟其行為。

使用CREATE[OR REPLACE] TYPE語句中建立的對象。下面是一個例子,建立包含一些屬性的簡單的位址對象:

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.

讓我們來建立一個多個客戶對象,包裝的屬性和方法,擁有面向對象的感覺:

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');      

比較方法被用于比較的對象。有兩種方法來比較對象:

  • 映射方法:映射方法它的值取決于屬性的值,以這樣的方式實作函數。例如,一個客戶對象,如果客戶代碼是相同的兩個客戶,可以認為是相同的一個。是以這兩個對象之間的關系将取決于代碼的值。
  • 順序方法:順序方法實作一些内部邏輯比較兩個對象。例如,對于矩形(rectangle)對象,如果其兩側都大,則表示矩形(rectangle)大于另一個矩形(rectangle)。

使用映射方法

讓我們試着去了解上面使用下面的矩形對象的概念:

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.

現在,使用矩形(rectangle)對象及其成員函數:

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.

使用順序的方法

現在,相同的效果可以使用順序方法來實作。讓我們用一個順序方法重新建立矩形(rectangle)對象:

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.

使用矩形(rectangle)對象及其成員函數:

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
/      

繼續閱讀