📅  最后修改于: 2020-11-26 06:05:23             🧑  作者: Mango
在本章中,我们将讨论面向对象的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方法是以其值取决于属性值的方式实现的函数。例如,对于一个客户对象,如果两个客户的客户代码相同,则两个客户可能相同。因此,这两个对象之间的关系将取决于代码的值。
Order方法实现了一些用于比较两个对象的内部逻辑。例如,对于矩形对象,如果矩形的两边都较大,则它大于另一个矩形。
让我们尝试使用以下矩形对象来理解以上概念-
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方法重新创建矩形对象-
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允许从现有基础对象创建对象。要实现继承,应将基础对象声明为NOT FINAL 。默认值为FINAL 。
以下程序说明了PL / SQL对象中的继承。让我们创建另一个名为TableTop的对象,该对象继承自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.
创建子对象桌面–
CREATE OR REPLACE TYPE tabletop UNDER rectangle
(
material varchar2(20),
OVERRIDING member procedure display
)
/
当以上代码在SQL提示符下执行时,将产生以下结果-
Type created.
为子对象桌面创建类型主体
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.
使用桌面对象及其成员函数-
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.
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.