在本章中,我們將討論面向對象的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提示符下執行時,它會產生以下結果 -
類型已創建。
下麵再創建另一個對象:customer
,將屬性和方法包裝在一起,以具有面向對象的感覺 -
CREATE OR REPLACE TYPE customer AS OBJECT
(
code number(5),
name varchar2(30),
contact_no varchar2(12),
addr address,
member procedure display
);
/
當上面的代碼在SQL提示符下執行時,它會產生以下結果 -
類型已創建。
實例化對象
定義對象類型為對象提供範本(或藍圖)。要使用這個對象,需要創建這個對象的實例。可以使用實例名稱和訪問運算符(.
)來訪問對象的屬性和方法,如下所示 -
SET SERVEROUTPUT ON SIZE 9999;
DECLARE
residence address;
BEGIN
residence := address('1502A', '人民大道', '海口', '海南','201901');
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('Province: '|| residence.state);
dbms_output.put_line('Pincode: '|| residence.pincode);
END;
/
執行上面示例代碼,得到以下結果 -
成員方法
成員方法用於操作對象的屬性。在聲明對象類型的同時提供成員方法的聲明。 對象體定義了成員方法的代碼。對象正文是使用CREATE TYPE BODY
語句創建的。
構造函數是返回一個新對象作為其值的函數。每個對象都有一個系統定義的構造方法。構造函數的名稱與對象類型相同。 例如 -
residence := address('1502A', '人民大道', '海口', '海南','201901');
比較方法用於比較對象。 有兩種方法來比較對象 -
映射方法
Map
方法是一個函數,它的值取決於屬性的值。 例如,對於客戶對象,如果客戶代碼對於兩個客戶是相同的,則兩個客戶可以是相同的。 所以這兩個對象之間的關係將取決於代碼的值。
排序方法
排序方法實現了一些用於比較兩個對象的內部邏輯。例如,對於一個矩形對象,如果矩形的兩邊都較大,則矩形比另一個矩形大。
使用Map方法
下麵嘗試使用以下矩形對象來瞭解上述概念 -
SET SERVEROUTPUT ON SIZE 999999;
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提示符下執行時,它會產生以下結果 -
類型已創建。
接下來,創建類型主體 -
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;
/
執行上面示例代碼,得到以下輸出結果 -
類型主體已創建。
現在使用矩形對象及其成員函數 -
SET SERVEROUTPUT ON SIZE 99999;
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;
/
執行上面示例代碼,得到以下輸出結果 -
使用排序方法
現在,使用排序方法可以達到同樣的效果。下麵來看看如使用排序方法重新創建矩形對象 -
CREATE OR REPLACE TYPE rectangle AS OBJECT
(
length number,
width number,
member procedure display,
order member function measure(r rectangle) return number
);
/
當上面的代碼在SQL提示符下執行時,它會產生以下結果 -
類型已創建。
創建類型主體 -
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;
/
執行上面示例代碼,得到以下結果 -
類型主體已創建。
使用矩形對象及其成員函數 -
SET SERVEROUTPUT ON SIZE 99999;
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;
/
執行上面示例代碼,得到以下結果 -
PL/SQL對象的繼承
PL/SQL允許從現有的基礎對象創建對象。為了實現繼承,基類對象應該聲明為NOT FINAL
。默認是FINAL
。
以下程式演示了PL/SQL對象中的繼承。首先創建另一個名為TableTop
對象,它是從Rectangle
對象繼承的。因此,需要創建這個基礎的Rectangle
對象,參考以下代碼 -
CREATE OR REPLACE TYPE rectangle FORCE AS OBJECT
(
length number,
width number,
member function enlarge( inc number) return rectangle,
NOT FINAL member procedure display) NOT FINAL
/
執行上面示例代碼,得到以下結果 -
類型已創建。
創建基本類型的主體 -
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;
/
執行上面示例代碼,得到以下結果 -
類型主體已創建。
創建子對象tabletop -
CREATE OR REPLACE TYPE tabletop UNDER rectangle
(
material varchar2(20),
OVERRIDING member procedure display
)
/
執行上面示例代碼,得到以下結果 -
類型已創建。
為子對象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;
/
執行上面示例代碼,得到以下結果 -
類型主體已創建。
使用tabletop
對象及其成員函數 -
DECLARE
t1 tabletop;
t2 tabletop;
BEGIN
t1:= tabletop(20, 10, 'Wood');
t2 := tabletop(50, 30, 'Steel');
t1.display;
t2.display;
END;
/
當執行上面示例代碼時,得到以下結果 -
Length: 20
Width: 10
Material: Wood
Length: 50
Width: 30
Material: Steel
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提示符下執行時,它會產生以下結果 -
類型已創建。