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

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

📁 sql初学者不错的教程
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;[<STRONG>OR</STRONG>&nbsp;REPLACE]&nbsp;<STRONG>TYPE</STRONG>&nbsp;type_name<BR>&nbsp;&nbsp;[<STRONG>AUTHID</STRONG>&nbsp;{CURRENT_USER&nbsp;|&nbsp;DEFINER}]<BR>&nbsp;&nbsp;{&nbsp;{<STRONG>IS</STRONG>&nbsp;|&nbsp;<STRONG>AS</STRONG>}&nbsp;OBJECT&nbsp;|&nbsp;UNDER&nbsp;supertype_name&nbsp;}<BR>(<BR>&nbsp;&nbsp;attribute_name&nbsp;datatype[,&nbsp;attribute_name&nbsp;datatype]...<BR>&nbsp;&nbsp;[{MAP&nbsp;|&nbsp;<STRONG>ORDER</STRONG>}&nbsp;MEMBER&nbsp;function_spec,]<BR>&nbsp;&nbsp;[{FINAL|&nbsp;<STRONG>NOT</STRONG>&nbsp;FINAL}&nbsp;MEMBER&nbsp;function_spec,]<BR>&nbsp;&nbsp;[{INSTANTIABLE|&nbsp;<STRONG>NOT</STRONG>&nbsp;INSTANTIABLE}&nbsp;MEMBER&nbsp;function_spec,]<BR>&nbsp;&nbsp;[{MEMBER&nbsp;|&nbsp;STATIC}&nbsp;{subprogram_spec&nbsp;|&nbsp;call_spec}<BR>&nbsp;&nbsp;[,&nbsp;{MEMBER&nbsp;|&nbsp;STATIC}&nbsp;{subprogram_spec&nbsp;|&nbsp;call_spec}]...]<BR>)&nbsp;[{FINAL|&nbsp;<STRONG>NOT</STRONG>&nbsp;FINAL}]&nbsp;[&nbsp;{INSTANTIABLE|&nbsp;<STRONG>NOT</STRONG>&nbsp;INSTANTIABLE}];<BR>[<STRONG>CREATE</STRONG>&nbsp;[<STRONG>OR</STRONG>&nbsp;REPLACE]&nbsp;<STRONG>TYPE</STRONG>&nbsp;<STRONG>BODY</STRONG>&nbsp;type_name&nbsp;{<STRONG>IS</STRONG>&nbsp;|&nbsp;<STRONG>AS</STRONG>}<BR>&nbsp;&nbsp;{&nbsp;{MAP&nbsp;|&nbsp;<STRONG>ORDER</STRONG>}&nbsp;MEMBER&nbsp;function_body;<BR>&nbsp;&nbsp;|&nbsp;{MEMBER&nbsp;|&nbsp;STATIC}&nbsp;{subprogram_body&nbsp;|&nbsp;call_spec};}<BR>&nbsp;&nbsp;[{MEMBER&nbsp;|&nbsp;STATIC}&nbsp;{subprogram_body&nbsp;|&nbsp;call_spec};]...<BR><STRONG>END</STRONG>;] 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P class=title2>1、PL/SQL类型继承一览</P>
                        <P>PL/SQL支持单继承模式。我们可以定义对象类型的子类型。这些子类型包括父类型(或超类)所有的属性和方法。子类型还可以包括额外的属性和方法,并可以覆盖超类的方法。 
                        </P>
                        <P>我们还可以定义子类是否能继承于某个特定的类型。我们也可以定义不能直接初始化的类型和方法,只有声明它们的子类才可以进行初始化操作。 
                        </P>
                        <P>有些类型属性可以用ALTER TYPE语句动态的改变。当基类发生变化时,无论是用ALTER 
                        TYPE语句还是重新定义基类,子类会自动的应用这些改变的内容。我们可以用TREAT操作符只返回某一个指定的子类的对象。 
                        </P>
                        <P>从REF和DEREF函数中产生的值可以代表声明过的表或视图类型,或是一个或多个它的子类型。 </P>
                        <UL>
                          <LI>PL/SQL类继承举例 </LI></UL>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><EM>--&nbsp;Create&nbsp;a&nbsp;supertype&nbsp;from&nbsp;which&nbsp;several&nbsp;subtypes&nbsp;will&nbsp;be&nbsp;derived.</EM><BR><BR><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;person_typ&nbsp;<STRONG>AS</STRONG>&nbsp;OBJECT(<BR>&nbsp;&nbsp;ssn&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>NUMBER</STRONG>,<BR>&nbsp;&nbsp;NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>(30),<BR>&nbsp;&nbsp;address&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>(100)<BR>)<BR><STRONG>NOT</STRONG>&nbsp;FINAL;<BR><BR><EM>--&nbsp;Derive&nbsp;a&nbsp;subtype&nbsp;that&nbsp;has&nbsp;all&nbsp;the&nbsp;attributes&nbsp;of&nbsp;the&nbsp;supertype,</EM><BR><EM>--&nbsp;plus&nbsp;some&nbsp;additional&nbsp;attributes.</EM><BR><BR><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;student_typ&nbsp;UNDER&nbsp;person_typ(<BR>&nbsp;&nbsp;deptid&nbsp;&nbsp;&nbsp;<STRONG>NUMBER</STRONG>,<BR>&nbsp;&nbsp;major&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>(30)<BR>)<BR><STRONG>NOT</STRONG>&nbsp;FINAL;<BR><BR><EM>--&nbsp;Because&nbsp;Student_typ&nbsp;is&nbsp;declared&nbsp;NOT&nbsp;FINAL,&nbsp;you&nbsp;can&nbsp;derive</EM><BR><EM>--&nbsp;further&nbsp;subtypes&nbsp;from&nbsp;it.</EM><BR><BR><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;parttimestudent_typ&nbsp;UNDER&nbsp;student_typ(<BR>&nbsp;&nbsp;numhours&nbsp;&nbsp;&nbsp;<STRONG>NUMBER</STRONG><BR>)<BR>;<BR><BR><EM>--&nbsp;Derive&nbsp;another&nbsp;subtype.&nbsp;Because&nbsp;it&nbsp;has&nbsp;the&nbsp;default&nbsp;attribute</EM><BR><EM>--&nbsp;FINAL,&nbsp;you&nbsp;cannot&nbsp;use&nbsp;Employee_typ&nbsp;as&nbsp;a&nbsp;supertype&nbsp;and&nbsp;derive</EM><BR><EM>--&nbsp;subtypes&nbsp;from&nbsp;it.</EM><BR><BR><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;employee_typ&nbsp;UNDER&nbsp;person_typ(<BR>&nbsp;&nbsp;empid&nbsp;&nbsp;&nbsp;<STRONG>NUMBER</STRONG>,<BR>&nbsp;&nbsp;mgr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>(30)<BR>)<BR>;<BR><BR><EM>--&nbsp;Define&nbsp;an&nbsp;object&nbsp;type&nbsp;that&nbsp;can&nbsp;be&nbsp;a&nbsp;supertype.&nbsp;Because&nbsp;the</EM><BR><EM>--&nbsp;member&nbsp;function&nbsp;is&nbsp;FINAL,&nbsp;it&nbsp;cannot&nbsp;be&nbsp;overridden&nbsp;in&nbsp;any</EM><BR><EM>--&nbsp;subtypes.</EM><BR><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;T&nbsp;<STRONG>AS</STRONG>&nbsp;OBJECT&nbsp;(...,&nbsp;MEMBER&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;Print(),&nbsp;FINAL&nbsp;MEMBER<BR><STRONG>FUNCTION</STRONG>&nbsp;foo(x&nbsp;<STRONG>NUMBER</STRONG>)...)&nbsp;<STRONG>NOT</STRONG>&nbsp;FINAL;<BR><EM>--&nbsp;We&nbsp;never&nbsp;want&nbsp;to&nbsp;create&nbsp;an&nbsp;object&nbsp;of&nbsp;this&nbsp;supertype.&nbsp;By&nbsp;using</EM><BR><EM>--&nbsp;NOT&nbsp;INSTANTIABLE,&nbsp;we&nbsp;force&nbsp;all&nbsp;objects&nbsp;to&nbsp;use&nbsp;one&nbsp;of&nbsp;the&nbsp;subtypes</EM><BR><EM>--&nbsp;instead,&nbsp;with&nbsp;specific&nbsp;implementations&nbsp;for&nbsp;the&nbsp;member&nbsp;functions.</EM><BR><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;Address_typ&nbsp;<STRONG>AS</STRONG>&nbsp;OBJECT(...)&nbsp;<STRONG>NOT</STRONG>&nbsp;INSTANTIABLE&nbsp;<STRONG>NOT</STRONG>&nbsp;FINAL;<BR><EM>--&nbsp;These&nbsp;subtypes&nbsp;can&nbsp;provide&nbsp;their&nbsp;own&nbsp;implementations&nbsp;of</EM><BR><EM>--&nbsp;member&nbsp;functions,&nbsp;such&nbsp;as&nbsp;for&nbsp;validating&nbsp;phone&nbsp;numbers&nbsp;and</EM><BR><EM>--&nbsp;postal&nbsp;codes.&nbsp;Because&nbsp;there&nbsp;is&nbsp;no&nbsp;"generic"&nbsp;way&nbsp;of&nbsp;doing&nbsp;these</EM><BR><EM>--&nbsp;things,&nbsp;only&nbsp;objects&nbsp;of&nbsp;these&nbsp;subtypes&nbsp;can&nbsp;be&nbsp;instantiated.</EM><BR><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;USAddress_typ&nbsp;UNDER&nbsp;Address_typ(...);<BR><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;IntlAddress_typ&nbsp;UNDER&nbsp;Address_typ(...);<BR><EM>--&nbsp;Return&nbsp;REFs&nbsp;for&nbsp;those&nbsp;Person_typ&nbsp;objects&nbsp;that&nbsp;are&nbsp;instances&nbsp;of</EM><BR><EM>--&nbsp;the&nbsp;Student_typ&nbsp;subtype,&nbsp;and&nbsp;<STRONG>NULL</STRONG>&nbsp;REFs&nbsp;otherwise.</EM><BR><STRONG>SELECT</STRONG>&nbsp;TREAT(<STRONG>REF</STRONG>(p)&nbsp;<STRONG>AS</STRONG>&nbsp;<STRONG>REF</STRONG>&nbsp;student_typ)<BR>&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;person_v&nbsp;p;<BR><EM>--&nbsp;Example&nbsp;of&nbsp;using&nbsp;TREAT&nbsp;for&nbsp;assignment...</EM><BR><EM>--&nbsp;Return&nbsp;REFs&nbsp;for&nbsp;those&nbsp;Person_type&nbsp;objects&nbsp;that&nbsp;are&nbsp;instances&nbsp;of</EM><BR><EM>--&nbsp;Employee_type&nbsp;or&nbsp;Student_typ,&nbsp;or&nbsp;any&nbsp;of&nbsp;their&nbsp;subtypes.</EM><BR><STRONG>SELECT</STRONG>&nbsp;<STRONG>REF</STRONG>(p)<BR>&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;person_v&nbsp;p<BR>&nbsp;<STRONG>WHERE</STRONG>&nbsp;VALUE(p)&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>OF</STRONG>(employee_typ,&nbsp;student_typ);<BR><EM>--&nbsp;Similar&nbsp;to&nbsp;above,&nbsp;but&nbsp;do&nbsp;not&nbsp;allow&nbsp;any&nbsp;subtypes&nbsp;of&nbsp;Student_typ.</EM><BR><STRONG>SELECT</STRONG>&nbsp;<STRONG>REF</STRONG>(p)<BR>&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;person_v&nbsp;p<BR>&nbsp;<STRONG>WHERE</STRONG>&nbsp;VALUE(p)&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>OF</STRONG>(ONLY&nbsp;student_typ);<BR><EM>--&nbsp;The&nbsp;results&nbsp;of&nbsp;REF&nbsp;and&nbsp;DEREF&nbsp;can&nbsp;include&nbsp;objects&nbsp;of&nbsp;Person_typ</EM><BR><EM>--&nbsp;and&nbsp;its&nbsp;subtypes&nbsp;such&nbsp;as&nbsp;Employee_typ&nbsp;and&nbsp;Student_typ.</EM><BR><STRONG>SELECT</STRONG>&nbsp;<STRONG>REF</STRONG>(p)<BR>&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;person_v&nbsp;p;<BR><STRONG>SELECT</STRONG>&nbsp;DEREF(<STRONG>REF</STRONG>(p))<BR>&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;person_v&nbsp;p; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P class=title2>2、对象类型实例:栈</P>
                        <P>栈是一个有序集合。栈有一个栈顶和一个栈底。栈中的每一项都只能在栈顶添加或删除。所以,最后一个被加入栈的项会被最先删除。(可以把栈想象成自助餐厅中的盘子。)压栈和退栈操作能够对栈进行后进先出(LIFO)更新。 
                        </P>
                        <P>栈能应用在很多地方。例如,它们可以用在系统编程中控制中断优先级并对递归进行管理。最简单的栈实现就是使用整数数组,数组的一端代表了栈顶。 
                        </P>
                        <P>PL/SQL提供了VARRAY数据类型,它能让我们声明变长数组。要声明变长数组属性,必须先定义变长数组类型。但是,我们不能再对象说明中定义类型,所以,我们只能单独的定义变长数组类型,并指定它的最大长度,具体实现如下: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;IntArray&nbsp;<STRONG>AS</STRONG>&nbsp;VARRAY(25)&nbsp;<STRONG>OF</STRONG>&nbsp;<STRONG>INTEGER</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>现在我们可以编写对象类型说明了:</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;stack&nbsp;<STRONG>AS</STRONG>&nbsp;OBJECT(<BR>&nbsp;&nbsp;max_size&nbsp;&nbsp;&nbsp;<STRONG>INTEGER</STRONG>,<BR>&nbsp;&nbsp;top&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INTEGER</STRONG>,<BR>&nbsp;&nbsp;POSITION&nbsp;&nbsp;&nbsp;intarray,<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;initialize,<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;FULL<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;<STRONG>BOOLEAN</STRONG>,<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;empty<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;<STRONG>BOOLEAN</STRONG>,<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;push(n&nbsp;<STRONG>IN</STRONG>&nbsp;<STRONG>INTEGER</STRONG>),<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;pop(n&nbsp;<STRONG>OUT</STRONG>&nbsp;<STRONG>INTEGER</STRONG>)<BR>); 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>最后,我们可以编写对象类型体:</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;<STRONG>BODY</STRONG>&nbsp;stack&nbsp;<STRONG>AS</STRONG><BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;initialize&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;top&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<EM>/*&nbsp;Call&nbsp;constructor&nbsp;for&nbsp;varray&nbsp;and&nbsp;set&nbsp;element&nbsp;1&nbsp;to&nbsp;NULL.&nbsp;*/</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;POSITION&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;intarray(<STRONG>NULL</STRONG>);<BR>&nbsp;&nbsp;&nbsp;&nbsp;max_size&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;POSITION.LIMIT;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;get&nbsp;varray&nbsp;size&nbsp;constraint</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;POSITION.EXTEND(max_size&nbsp;-&nbsp;1,&nbsp;1);&nbsp;&nbsp;&nbsp;<EM>--&nbsp;copy&nbsp;element&nbsp;1&nbsp;into&nbsp;2..25</EM><BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;initialize;<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;FULL<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;<STRONG>BOOLEAN</STRONG>&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>(top&nbsp;=&nbsp;max_size);&nbsp;&nbsp;&nbsp;<EM>--&nbsp;return&nbsp;TRUE&nbsp;if&nbsp;stack&nbsp;is&nbsp;full</EM><BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;FULL;<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;empty<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;<STRONG>BOOLEAN</STRONG>&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>(top&nbsp;=&nbsp;0);&nbsp;&nbsp;&nbsp;<EM>--&nbsp;return&nbsp;TRUE&nbsp;if&nbsp;stack&nbsp;is&nbsp;empty</EM><BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;empty;<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;push(n&nbsp;<STRONG>IN</STRONG>&nbsp;<STRONG>INTEGER</STRONG>)&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>IF</STRONG>&nbsp;<STRONG>NOT</STRONG>&nbsp;FULL&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;top&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;top&nbsp;+&nbsp;1;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;push&nbsp;integer&nbsp;onto&nbsp;stack</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;POSITION(top)&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;n;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>ELSE</STRONG>&nbsp;&nbsp;&nbsp;<EM>--&nbsp;stack&nbsp;is&nbsp;full</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise_application_error(-20101,&nbsp;<EM>'stack&nbsp;overflow'</EM>);<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>IF</STRONG>;<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;push;<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;pop(n&nbsp;<STRONG>OUT</STRONG>&nbsp;<STRONG>INTEGER</STRONG>)&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>IF</STRONG>&nbsp;<STRONG>NOT</STRONG>&nbsp;empty&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;POSITION(top);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;top&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;top&nbsp;-&nbsp;1;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;pop&nbsp;integer&nbsp;off&nbsp;stack</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>ELSE</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;stack&nbsp;is&nbsp;empty</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise_application_error(-20102,&nbsp;<EM>'stack&nbsp;underflow'</EM>);<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>IF</STRONG>;<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;pop;<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>在成员过程push和pop中,我们使用内置过程raise_application_error来关联用户定义的错误消息。这样,我们就能把错误报告给客户端程序而避免把未控制异常传给主环境。客户端程序捕获PL/SQL异常后,可以在OTHERS异常控制句柄中用SQLCODE和SQLERRM 
                        来确定具体的错误信息。下例中,当异常被抛出时,我们就把对应的错误消息输出: </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;...<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;...<BR><STRONG>EXCEPTION</STRONG><BR>&nbsp;&nbsp;<STRONG>WHEN</STRONG>&nbsp;<STRONG>OTHERS</STRONG>&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;dbms_output.put_line(<STRONG>SQLERRM</STRONG>);<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>另外,程序还可以使用编译指示EXCEPTION_INIT把raise_application_error返回的错误编号影射到命名异常中,如下例所示:</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;stack_overflow&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>EXCEPTION</STRONG>;<BR>&nbsp;&nbsp;stack_underflow&nbsp;&nbsp;&nbsp;<STRONG>EXCEPTION</STRONG>;<BR>&nbsp;&nbsp;<STRONG>PRAGMA</STRONG>&nbsp;EXCEPTION_INIT(stack_overflow,&nbsp;-20101);<BR>&nbsp;&nbsp;<STRONG>PRAGMA</STRONG>&nbsp;EXCEPTION_INIT(stack_underflow,&nbsp;-20102);<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;...<BR><STRONG>EXCEPTION</STRONG><BR>&nbsp;&nbsp;<STRONG>WHEN</STRONG>&nbsp;stack_overflow&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;...<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P class=title2>3、对象类型实例:售票处</P>
                        <P>假如有一个连锁电影院,每个影院有三个银幕。每个影院有一个售票处,销售三种不同电影的影票。所有影票的价格都为三美元。定期检查影票的销售情况,然后及时补充影票。 
                        </P>
                        <P>在定义代表销售处的对象类型之前,我们必须考虑到必要的数据和操作。对于一个简单的售票处来说,对象类型需要票价、当前影票存量和已售影票的收据这些属性。它还需要一些方法:购票、盘存、补充存量和收集收据。 
                        </P>
                        <P>对于收据,我们可以使用含有三个元素的数组。元素1、2和3各自记录电影1、2和3。要声明一个变长数组属性,我们就必须先像下面这样定义它的类型: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;RealArray&nbsp;<STRONG>AS</STRONG>&nbsp;VARRAY(3)&nbsp;<STRONG>OF</STRONG>&nbsp;<STRONG>REAL</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>现在,我们可以编写对象类型说明: </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;ticket_booth&nbsp;<STRONG>AS</STRONG>&nbsp;OBJECT(<BR>&nbsp;&nbsp;price&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>,<BR>&nbsp;&nbsp;qty_on_hand&nbsp;&nbsp;&nbsp;<STRONG>INTEGER</STRONG>,<BR>&nbsp;&nbsp;receipts&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;realarray,<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;initialize,<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;purchase(movie&nbsp;<STRONG>INTEGER</STRONG>,&nbsp;amount&nbsp;<STRONG>REAL</STRONG>,&nbsp;CHANGE&nbsp;<STRONG>OUT</STRONG>&nbsp;<STRONG>REAL</STRONG>),<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;inventory<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;<STRONG>INTEGER</STRONG>,<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;replenish(quantity&nbsp;<STRONG>INTEGER</STRONG>),<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;<STRONG>COLLECT</STRONG>(movie&nbsp;<STRONG>INTEGER</STRONG>,&nbsp;amount&nbsp;<STRONG>OUT</STRONG>&nbsp;<STRONG>REAL</STRONG>)<BR>); 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>最后,我们可以编写对象类型体: </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;<STRONG>BODY</STRONG>&nbsp;ticket_booth&nbsp;<STRONG>AS</STRONG><BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;initialize&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;price&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;3.00;<BR>&nbsp;&nbsp;&nbsp;&nbsp;qty_on_hand&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;5000;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;provide&nbsp;initial&nbsp;stock&nbsp;of&nbsp;tickets</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;call&nbsp;constructor&nbsp;for&nbsp;varray&nbsp;and&nbsp;set&nbsp;elements&nbsp;1..3&nbsp;to&nbsp;zero</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;receipts&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;realarray(0,&nbsp;0,&nbsp;0);<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;initialize;<BR>&nbsp;&nbsp;MEMBER&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;purchase(movie&nbsp;<STRONG>INTEGER</STRONG>,&nbsp;amount&nbsp;<STRONG>REAL</STRONG>,&nbsp;CHANGE&nbsp;<STRONG>OUT</STRONG>&nbsp;<STRONG>REAL</STRONG>)&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>IF</STRONG>&nbsp;qty_on_hand&nbsp;=&nbsp;0&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise_application_error(-20103,&nbsp;<EM>'out&nbsp;of&nbsp;stock'</EM>);<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>IF</STRONG>;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>IF</STRONG>&nbsp;amount&nbsp;&gt;=&nbsp;price&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;qty_on_hand&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;qty_on_hand&nbsp;-&nbsp;1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;receipts(movie)&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;receipts(movie)&nbsp;+&nbsp;price;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CHANGE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;amount&nbsp;-&nbsp;price;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>ELSE</STRONG>&nbsp;&nbsp;&nbsp;<EM>--&nbsp;amount&nbsp;is&nbsp;not&nbsp;enough</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CHANGE&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;amount;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;so&nbsp;return&nbsp;full&nbsp;amount</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STR

⌨️ 快捷键说明

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