在本章中,我們將討論面向?qū)ο蟮腜L/SQL。 PL/SQL允許定義一個對象類型,這有助于在Oracle中設(shè)計面向?qū)ο蟮臄?shù)據(jù)庫。 對象類型允許創(chuàng)建復(fù)合類型。使用對象可實現(xiàn)具有特定數(shù)據(jù)結(jié)構(gòu)的真實世界對象以及操作它的方法。對象具有屬性和方法。對象的屬性用于存儲對象的狀態(tài); 并使用方法來建模其行為。
對象是使用CREATE [OR REPLACE] TYPE語句創(chuàng)建的。 以下是創(chuàng)建一個由幾個屬性組成的簡單地址(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
當(dāng)上面的代碼在SQL提示符下執(zhí)行時,它會產(chǎn)生以下結(jié)果 -
類型已創(chuàng)建。
下面再創(chuàng)建另一個對象:customer,將屬性和方法包裝在一起,以具有面向?qū)ο蟮母杏X -
CREATE OR REPLACE TYPE customer AS OBJECT
(
code number(5),
name varchar2(30),
contact_no varchar2(12),
addr address,
member procedure display
);
/
SQL
當(dāng)上面的代碼在SQL提示符下執(zhí)行時,它會產(chǎn)生以下結(jié)果 -
類型已創(chuàng)建。
定義對象類型為對象提供模板(或藍(lán)圖)。要使用這個對象,需要創(chuàng)建這個對象的實例。可以使用實例名稱和訪問運算符(.)來訪問對象的屬性和方法,如下所示 -
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;
/
SQL
執(zhí)行上面示例代碼,得到以下結(jié)果 -
成員方法用于操作對象的屬性。在聲明對象類型的同時提供成員方法的聲明。 對象體定義了成員方法的代碼。對象正文是使用CREATE TYPE BODY語句創(chuàng)建的。
構(gòu)造函數(shù)是返回一個新對象作為其值的函數(shù)。每個對象都有一個系統(tǒng)定義的構(gòu)造方法。構(gòu)造函數(shù)的名稱與對象類型相同。 例如 -
residence := address('1502A', '人民大道', '???, '海南','201901');
SQL
比較方法用于比較對象。 有兩種方法來比較對象 -
映射方法
Map方法是一個函數(shù),它的值取決于屬性的值。 例如,對于客戶對象,如果客戶代碼對于兩個客戶是相同的,則兩個客戶可以是相同的。 所以這兩個對象之間的關(guān)系將取決于代碼的值。
排序方法
排序方法實現(xiàn)了一些用于比較兩個對象的內(nèi)部邏輯。例如,對于一個矩形對象,如果矩形的兩邊都較大,則矩形比另一個矩形大。
下面嘗試使用以下矩形對象來了解上述概念 -
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
當(dāng)上面的代碼在SQL提示符下執(zhí)行時,它會產(chǎn)生以下結(jié)果 -
類型已創(chuàng)建。
接下來,創(chuàng)建類型主體 -
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
執(zhí)行上面示例代碼,得到以下輸出結(jié)果 -
類型主體已創(chuàng)建。
Shell
現(xiàn)在使用矩形對象及其成員函數(shù) -
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;
/
SQL
執(zhí)行上面示例代碼,得到以下輸出結(jié)果 -
現(xiàn)在,使用排序方法可以達(dá)到同樣的效果。下面來看看如使用排序方法重新創(chuàng)建矩形對象 -
CREATE OR REPLACE TYPE rectangle AS OBJECT
(
length number,
width number,
member procedure display,
order member function measure(r rectangle) return number
);
/
SQL
當(dāng)上面的代碼在SQL提示符下執(zhí)行時,它會產(chǎn)生以下結(jié)果 -
類型已創(chuàng)建。
創(chuàng)建類型主體 -
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
執(zhí)行上面示例代碼,得到以下結(jié)果 -
類型主體已創(chuàng)建。
Shell
使用矩形對象及其成員函數(shù) -
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;
/
SQL
執(zhí)行上面示例代碼,得到以下結(jié)果 -
PL/SQL允許從現(xiàn)有的基礎(chǔ)對象創(chuàng)建對象。為了實現(xiàn)繼承,基類對象應(yīng)該聲明為NOT FINAL。默認(rèn)是FINAL。
以下程序演示了PL/SQL對象中的繼承。首先創(chuàng)建另一個名為TableTop對象,它是從Rectangle對象繼承的。因此,需要創(chuàng)建這個基礎(chǔ)的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
/
SQL
執(zhí)行上面示例代碼,得到以下結(jié)果 -
類型已創(chuàng)建。
Shell
創(chuàng)建基本類型的主體 -
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
執(zhí)行上面示例代碼,得到以下結(jié)果 -
類型主體已創(chuàng)建。
Shell
創(chuàng)建子對象tabletop -
CREATE OR REPLACE TYPE tabletop UNDER rectangle
(
material varchar2(20),
OVERRIDING member procedure display
)
/
SQL
執(zhí)行上面示例代碼,得到以下結(jié)果 -
類型已創(chuàng)建。
Shell
為子對象tabletop創(chuàng)建類型主體 -
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
執(zhí)行上面示例代碼,得到以下結(jié)果 -
類型主體已創(chuàng)建。
Shell
使用tabletop對象及其成員函數(shù) -
DECLARE
t1 tabletop;
t2 tabletop;
BEGIN
t1:= tabletop(20, 10, 'Wood');
t2 := tabletop(50, 30, 'Steel');
t1.display;
t2.display;
END;
/
SQL
當(dāng)執(zhí)行上面示例代碼時,得到以下結(jié)果 -
Length: 20
Width: 10
Material: Wood
Length: 50
Width: 30
Material: Steel
Shell
NOT INSTANTIABLE子句用來聲明一個抽象對象。不能直接使用抽象對象, 必須創(chuàng)建抽象對象的子類型或子類型才能使用它的功能。
例如,
CREATE OR REPLACE TYPE rectangle AS OBJECT
(length number,
width number,
NOT INSTANTIABLE NOT FINAL MEMBER PROCEDURE display)
NOT INSTANTIABLE NOT FINAL
/
SQL
當(dāng)上面的代碼在SQL提示符下執(zhí)行時,它會產(chǎn)生以下結(jié)果 -
類型已創(chuàng)建。
更多建議: