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 /

當上述代碼在SQL提示符執行時,它產生了以下結果:

Type created.