PL/SQL - 面向物件



本章將討論面向物件的 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'); 

比較方法用於比較物件。有兩種比較物件的方法:

Map 方法

Map 方法是一個以這樣的方式實現的函式:其值取決於屬性的值。例如,對於客戶物件,如果兩個客戶的客戶程式碼相同,則這兩個客戶可能相同。因此,這兩個物件之間的關係將取決於程式碼的值。

Order 方法

Order 方法實現了一些用於比較兩個物件的內部邏輯。例如,對於矩形物件,如果矩形的兩條邊都更大,則一個矩形大於另一個矩形。

使用 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 方法

現在,可以使用 Order 方法實現相同的效果。讓我們使用 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.
廣告