⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 第十章 pl-sql对象类型 - pl-sql用户指南与参考 - whatiswhat.htm

📁 sql初学者不错的教程
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                  <TABLE 
                  style="BORDER-COLLAPSE: collapse; WORD-WRAP: break-word" 
                  cellSpacing=0 cellPadding=0 width="100%" border=0>
                    <TBODY>
                    <TR>
                      <TD>
                        <DIV id=art style="MARGIN: 15px">
                        <CENTER><IMG alt="" 
                        src="第十章 PL-SQL对象类型 - PL-SQL用户指南与参考 - whatiswhat.files/o_cover.jpg"><BR><IMG 
                        alt="" 
                        src="第十章 PL-SQL对象类型 - PL-SQL用户指南与参考 - whatiswhat.files/o_banner.gif"> 
                        </CENTER>
                        <DIV id=chapter>第十章 PL/SQL对象类型 </DIV><!-- InstanceEndEditable --><!-- InstanceBeginEditable name="EditRegion2"  -->
                        <P class=title1>一、抽象的角色</P>
                        <P>抽象是对一个真实世界实体的高级描述或建模。它能排除掉无关的细节内容,使我们的日常生活更有条理。例如,驾驶一辆汽车时,我们是不需要知道它的发动机是如何工作的。由变速排档、方向盘、加速器和刹车组成的接口就能让我们有效地使用它。而其中每一项的详细信息对于日常驾驶来说并不重要。 
                        </P>
                        <P>抽象是编程的核心内容。例如,我们在隐藏一个复杂的算法时只要编写一个过程,然后为它传递参数就可以做到过程化抽象。如果需要改变具体的实现,换一个过程体即可。有了抽象后,那些调用过程的程序就不需要再修改了。 
                        </P>
                        <P>我们在指定变量的数据类型时,可以使用数据抽象。数据类型代表了对于想操作的数值的值集合和操作符集合。比如说一个POSITIVE类型的变量,只能存放正整数,也只能用于加减乘等运算。使用这个变量时,我们不必知道PL/SQL是如何存储整数或是实现算术运算的。 
                        </P>
                        <P>对象类型是大多数编程语言内置类型的一个概括。PL/SQL提供了大量的标量类型和复合类型,每种类型都与一组预定义操作符相关联。标量类型(如 
                        CHAR)是没有内部组成成分的。但复合类型(如RECORD)是有内部组成成分的,并且其中每一个部分都可以被独立操作。同RECORD类型一样,对象类型也是复合类型。但是,它的操作是用户自定义的,而不是预定义的。 
                        </P>
                        <P>目前,我们还不能用PL/SQL定义对象类型。它们必须用CREATE语句创建并存放在Oracle数据库中,这样才能被许多程序所共享。使用对象类型的程序称为客户端程序,它可以声明并操作对象,但并不要求知道对象类型是如何表现数据或实现操作。这就能够让我们分别编写程序和对象类型,即便是在改变了对象实现时也不会影响到程序。因此,对象类型既支持过程化和又支持数据抽象。 
                        </P>
                        <P class=title1>二、什么是对象类型</P>
                        <P>对象类型是一个用户自定义复合类型,它封装了数据结构和操作这个数据结构的函数和过程。数据结构中的变量称为属性,函数和过程称为方法。通常,我们认为对象(如人、车、银行账户)都是有着属性和行为的。例如一个婴儿有性别、年龄和体重这些属性,行为有吃、喝、睡等。对象类型能够让我们把这些内容抽象出来并在应用程序中使用。 
                        </P>
                        <P>使用CREATE 
                        TYPE语句创建对象类型的时候,我们实际上是创建了真实世界中某个对象的抽象模板。模板只指定了我们在程序中能用到的属性和行为。比如一个雇员有很多属性,但通常只有他的一部分信息是我们的应用程序所需要的,见下图: 
                        </P><IMG alt="" 
                        src="第十章 PL-SQL对象类型 - PL-SQL用户指南与参考 - whatiswhat.files/o_10-1.gif"> 

                        <P>假设我们现在需要编写一个为雇员分发奖金的程序。因为并不是雇员的所有属性都能用于解决这个问题,所以,我们只需设计一个抽象的雇员,拥有与解决问题相关的属性即可:姓名、ID号、部门、职称、工资和级别。然后,设计一些具体的操作方法,例如更改雇员的级别。 
                        </P>
                        <P>下一步就是定义用于数据表现的变量(属性)和用于执行操作的子程序集(方法)。最后,我们把属性和方法封装到对象类型中去。 
                        </P>
                        <P>对象的属性是公有的(对客户端程序可见)。但是,设计良好的程序是不应该直接操作这些属性的,我们应该为这些操作编写相应的方法。这样,雇员数据就能保存在一个合适的状态。 
                        </P>
                        <P>在运行时,我们可以建立抽象雇员的实例(通常称为对象),然后为它的属性赋值。我们可以按照我们的需求创建任意多个实例。每个对象都有姓名、编号、职别等,如下图所示: 
                        </P><IMG alt="" 
                        src="第十章 PL-SQL对象类型 - PL-SQL用户指南与参考 - whatiswhat.files/o_10-2.gif"> 

                        <P class=title1>三、为什么使用对象类型</P>
                        <P>对象类型能把大的系统划分为多个逻辑实体,简化系统复杂度。这就使我们可以创建模块化、可维护、可重用的组件。也能让不同小组的程序员并行开发软件组件。 
                        </P>
                        <P>对象类型靠封装数据的操作来把数据维护代码从SQL脚本中分离出来,并把PL/SQL块封装到方法里。使用对象方法可以避免很多在数据访问时带来的负面影响,同时,对象类型隐藏实现细节,更新细节内容时不必修改客户端程序。 
                        </P>
                        <P>对象类型可以为现实数据建模。现实世界中的复杂实体和关系都可以直接映射到对象类型中。并且,对象类型还可以直接映射到面向对象语言(如Java和C++)的类中。 
                        </P>
                        <P class=title1>四、对象类型的结构</P>
                        <P>与包相同,对象类型也有两部分:说明和体,如下图所示。说明部分是应用程序接口;它声明了数据结构(属性集合)和所需的操作(方法)。方法体部分是对已声明方法的实现。 
                        </P><IMG alt="" 
                        src="第十章 PL-SQL对象类型 - PL-SQL用户指南与参考 - whatiswhat.files/o_10-3.gif"> 

                        <P>客户端程序要使用到的所有方法都在说明中声明。我们可以把对象说明想象成一个可选的接口,把对象体想象成一个黒盒。我们可以在不改变说明部分的前提下调试,增强或替换对象体,并且不会对客户端程序造成影响。 
                        </P>
                        <P>在一个对象说明中,所有的属性都必须声明在方法之前。只有子程序的声明才需要实现。所以,如果一个对象类型的说明只声明了属性,那么对象类型的体就没有必要了。我们不能在对象体中声明属性。对象说明中的声明都是公有的。 
                        </P>
                        <P>为了能更好的了解结构,请看下面的例子。这是一个复数的对象类型,有实数部分和虚数部分,并有几个与复数操作相关的方法。 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;complex&nbsp;<STRONG>AS</STRONG>&nbsp;OBJECT(<BR>&nbsp;&nbsp;rpart&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>,&nbsp;&nbsp;&nbsp;<EM>--&nbsp;attribute</EM><BR>&nbsp;&nbsp;ipart&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>,<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;plus(x&nbsp;complex)<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;complex,&nbsp;&nbsp;&nbsp;<EM>--&nbsp;method</EM><BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;LESS(x&nbsp;complex)<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;complex,<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;times(x&nbsp;complex)<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;complex,<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;divby(x&nbsp;complex)<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;complex<BR>);<BR><BR><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;<STRONG>BODY</STRONG>&nbsp;complex&nbsp;<STRONG>AS</STRONG><BR><BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;plus(x&nbsp;complex)<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;complex&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;complex(rpart&nbsp;+&nbsp;x.rpart,&nbsp;ipart&nbsp;+&nbsp;x.ipart);<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;plus;<BR><BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;LESS(x&nbsp;complex)<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;complex&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;complex(rpart&nbsp;-&nbsp;x.rpart,&nbsp;ipart&nbsp;-&nbsp;x.ipart);<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;LESS;<BR><BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;times(x&nbsp;complex)<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;complex&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;complex(rpart&nbsp;*&nbsp;x.rpart&nbsp;-&nbsp;ipart&nbsp;*&nbsp;x.ipart,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rpart&nbsp;*&nbsp;x.ipart&nbsp;+&nbsp;ipart&nbsp;*&nbsp;x.rpart);<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;times;<BR><BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;divby(x&nbsp;complex)<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;complex&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;z&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>&nbsp;:=&nbsp;x.rpart&nbsp;**&nbsp;2&nbsp;+&nbsp;x.ipart&nbsp;**&nbsp;2;<BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;complex((rpart&nbsp;*&nbsp;x.rpart&nbsp;+&nbsp;ipart&nbsp;*&nbsp;x.ipart)&nbsp;/&nbsp;z,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ipart&nbsp;*&nbsp;x.rpart&nbsp;-&nbsp;rpart&nbsp;*&nbsp;x.ipart)&nbsp;/&nbsp;z);<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;divby;<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P class=title1>五、对象类型组件</P>
                        <P>对象类型封装了数据和操作。我们可以在对象类型说明中声明属性和方法,但不能声明常量、异常、游标或类型。我们至少要声明一个属性(最多1000个),方法是可选的。 
                        </P>
                        <P class=title2>1、属性</P>
                        <P>同变量一样,属性也有名称和数据类型。对象类型中的名称必须是唯一的(但在其他的对象类型中可以重用)。除了下面几种类型之外,其他任何Oralce类型都可以使用: 
                        </P>
                        <OL>
                          <LI>LONG和LONG RAW 
                          <LI>ROWID和UROWID 
                          <LI>PL/SQL特定类型BINARY_INTEGER及它的子类型、BOOLEAN、PLS_INTEGER、RECORD、REF 
                          CURSOR、%TYPE和%ROWTYPE 
                          <LI>PL/SQL包内定义的数据类型 </LI></OL>
                        <P>我们不能在声明属性的时候用赋值语句或DEFAULT子句为它初始化。同样,也不能对属性应用NOT 
                        NULL约束。但是,对象是可以存放到添加了约束的数据表中。 </P>
                        <P>数据结构中的属性集合依赖于真实世界中的对象。例如,为了表现一个分数,我们只需要两个INTEGER类型的变量。另一方面,要是表现一个学生,我们需要几个VARCHAR2来存放姓名、住址、电话号码和状态等,再添加一个VARRAY类型变量用来存储课程和分数。 
                        </P>
                        <P>数据结构可能是复杂的。例如,一个属性的数据类型可能是另外一个对象类型(称为嵌套对象类型)。有些对象类型,像队列、链表和树,都是动态的,它们是随着使用的需要而动态改变存储长度的。递归对象类型能够直接或间接的包含自身类型,这样就能创建出更诡异的数据类型。 
                        </P>
                        <P class=title2>2、方法</P>
                        <P>一般的,方法就是用关键字MEMBER或STATIC声明在对象说明部分的子程序。方法名不能和对象类型名、属性名重复。MEMBER方法只能通过对象实例调用,如: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD noWrap>instance_expression.method() 
                            </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>但是,STATIC方法直接通过对象类型调用,而不是实例,如:</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -