PL/SQL - 面向对象

在本章中,我们将讨论面向对象的 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 提示符下执行上述代码时,会产生以下结果 −

Type created. 

让我们再创建一个 customer 对象,我们将把 attributesmethods 包装在一起,以获得面向对象的感觉 −

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。 默认值为最终

以下程序说明了 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.