![PL SQL 用戶指南和參考第十章PLSQL對(duì)象類型_第1頁](http://file3.renrendoc.com/fileroot_temp3/2021-12/15/79e1e588-38a3-4ddc-998e-8e3a61332e36/79e1e588-38a3-4ddc-998e-8e3a61332e361.gif)
![PL SQL 用戶指南和參考第十章PLSQL對(duì)象類型_第2頁](http://file3.renrendoc.com/fileroot_temp3/2021-12/15/79e1e588-38a3-4ddc-998e-8e3a61332e36/79e1e588-38a3-4ddc-998e-8e3a61332e362.gif)
![PL SQL 用戶指南和參考第十章PLSQL對(duì)象類型_第3頁](http://file3.renrendoc.com/fileroot_temp3/2021-12/15/79e1e588-38a3-4ddc-998e-8e3a61332e36/79e1e588-38a3-4ddc-998e-8e3a61332e363.gif)
![PL SQL 用戶指南和參考第十章PLSQL對(duì)象類型_第4頁](http://file3.renrendoc.com/fileroot_temp3/2021-12/15/79e1e588-38a3-4ddc-998e-8e3a61332e36/79e1e588-38a3-4ddc-998e-8e3a61332e364.gif)
![PL SQL 用戶指南和參考第十章PLSQL對(duì)象類型_第5頁](http://file3.renrendoc.com/fileroot_temp3/2021-12/15/79e1e588-38a3-4ddc-998e-8e3a61332e36/79e1e588-38a3-4ddc-998e-8e3a61332e365.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第十章 PL/SQL對(duì)象類型一、抽象的角色抽象是對(duì)一個(gè)真實(shí)世界實(shí)體的高級(jí)描述或建模。它能排除掉無關(guān)的細(xì)節(jié)內(nèi)容,使我們的日常生活更有條理。例如,駕駛一輛汽車時(shí),我們是不需要知道它的發(fā)動(dòng)機(jī)是如何工作的。由變速排檔、方向盤、加速器和剎車組成的接口就能讓我們有效地使用它。而其中每一項(xiàng)的詳細(xì)信息對(duì)于日常駕駛來說并不重要。 抽象是編程的核心內(nèi)容。例如,我們?cè)陔[藏一個(gè)復(fù)雜的算法時(shí)只要編寫一個(gè)過程,然后為它傳遞參數(shù)就可以做到過程化抽象。如果需要改變具體的實(shí)現(xiàn),換一個(gè)過程體即可。有了抽象后,那些調(diào)用過程的程序就不需要再修改了。 我們?cè)谥付ㄗ兞康臄?shù)據(jù)類型時(shí),可以使用數(shù)據(jù)抽象。數(shù)據(jù)類型代表了對(duì)于想操作的數(shù)值的值集合
2、和操作符集合。比方說一個(gè)POSITIVE類型的變量,只能存放正整數(shù),也只能用于加減乘等運(yùn)算。使用這個(gè)變量時(shí),我們不必知道PL/SQL是如何存儲(chǔ)整數(shù)或是實(shí)現(xiàn)算術(shù)運(yùn)算的。 對(duì)象類型是大多數(shù)編程語言內(nèi)置類型的一個(gè)概括。PL/SQL提供了大量的標(biāo)量類型和復(fù)合類型,每種類型都與一組預(yù)定義操作符相關(guān)聯(lián)。標(biāo)量類型(如 CHAR)是沒有內(nèi)部組成成分的。但復(fù)合類型(如RECORD)是有內(nèi)部組成成分的,并且其中每一個(gè)局部都可以被獨(dú)立操作。同RECORD類型一樣,對(duì)象類型也是復(fù)合類型。但是,它的操作是用戶自定義的,而不是預(yù)定義的。 目前,我們還不能用PL/SQL定義對(duì)象類型。它們必須用CREATE語句創(chuàng)立并存放在O
3、racle數(shù)據(jù)庫中,這樣才能被許多程序所共享。使用對(duì)象類型的程序稱為客戶端程序,它可以聲明并操作對(duì)象,但并不要求知道對(duì)象類型是如何表現(xiàn)數(shù)據(jù)或?qū)崿F(xiàn)操作。這就能夠讓我們分別編寫程序和對(duì)象類型,即便是在改變了對(duì)象實(shí)現(xiàn)時(shí)也不會(huì)影響到程序。因此,對(duì)象類型既支持過程化和又支持?jǐn)?shù)據(jù)抽象。 二、什么是對(duì)象類型對(duì)象類型是一個(gè)用戶自定義復(fù)合類型,它封裝了數(shù)據(jù)結(jié)構(gòu)和操作這個(gè)數(shù)據(jù)結(jié)構(gòu)的函數(shù)和過程。數(shù)據(jù)結(jié)構(gòu)中的變量稱為屬性,函數(shù)和過程稱為方法。通常,我們認(rèn)為對(duì)象(如人、車、銀行賬戶)都是有著屬性和行為的。例如一個(gè)嬰兒有性別、年齡和體重這些屬性,行為有吃、喝、睡等。對(duì)象類型能夠讓我們把這些內(nèi)容抽象出來并在應(yīng)用程序中使用。
4、 使用CREATE TYPE語句創(chuàng)立對(duì)象類型的時(shí)候,我們實(shí)際上是創(chuàng)立了真實(shí)世界中某個(gè)對(duì)象的抽象模板。模板只指定了我們?cè)诔绦蛑心苡玫降膶傩院托袨?。比方一個(gè)雇員有很多屬性,但通常只有他的一局部信息是我們的應(yīng)用程序所需要的,見以下圖: 假設(shè)我們現(xiàn)在需要編寫一個(gè)為雇員分發(fā)獎(jiǎng)金的程序。因?yàn)椴⒉皇枪蛦T的所有屬性都能用于解決這個(gè)問題,所以,我們只需設(shè)計(jì)一個(gè)抽象的雇員,擁有與解決問題相關(guān)的屬性即可:姓名、ID號(hào)、部門、職稱、工資和級(jí)別。然后,設(shè)計(jì)一些具體的操作方法,例如更改雇員的級(jí)別。 下一步就是定義用于數(shù)據(jù)表現(xiàn)的變量(屬性)和用于執(zhí)行操作的子程序集(方法)。最后,我們把屬性和方法封裝到對(duì)象類型中去。 對(duì)象的
5、屬性是公有的(對(duì)客戶端程序可見)。但是,設(shè)計(jì)良好的程序是不應(yīng)該直接操作這些屬性的,我們應(yīng)該為這些操作編寫相應(yīng)的方法。這樣,雇員數(shù)據(jù)就能保存在一個(gè)適宜的狀態(tài)。 在運(yùn)行時(shí),我們可以建立抽象雇員的實(shí)例(通常稱為對(duì)象),然后為它的屬性賦值。我們可以按照我們的需求創(chuàng)立任意多個(gè)實(shí)例。每個(gè)對(duì)象都有姓名、編號(hào)、職別等,如以下圖所示: 三、為什么使用對(duì)象類型對(duì)象類型能把大的系統(tǒng)劃分為多個(gè)邏輯實(shí)體,簡化系統(tǒng)復(fù)雜度。這就使我們可以創(chuàng)立模塊化、可維護(hù)、可重用的組件。也能讓不同小組的程序員并行開發(fā)軟件組件。 對(duì)象類型靠封裝數(shù)據(jù)的操作來把數(shù)據(jù)維護(hù)代碼從SQL腳本中別離出來,并把PL/SQL塊封裝到方法里。使用對(duì)象方法可以
6、防止很多在數(shù)據(jù)訪問時(shí)帶來的負(fù)面影響,同時(shí),對(duì)象類型隱藏實(shí)現(xiàn)細(xì)節(jié),更新細(xì)節(jié)內(nèi)容時(shí)不必修改客戶端程序。 對(duì)象類型可以為現(xiàn)實(shí)數(shù)據(jù)建模?,F(xiàn)實(shí)世界中的復(fù)雜實(shí)體和關(guān)系都可以直接映射到對(duì)象類型中。并且,對(duì)象類型還可以直接映射到面向?qū)ο笳Z言(如Java和C+)的類中。 四、對(duì)象類型的結(jié)構(gòu)與包相同,對(duì)象類型也有兩局部:說明和體,如以下圖所示。說明局部是應(yīng)用程序接口;它聲明了數(shù)據(jù)結(jié)構(gòu)(屬性集合)和所需的操作(方法)。方法體局部是對(duì)已聲明方法的實(shí)現(xiàn)。 客戶端程序要使用到的所有方法都在說明中聲明。我們可以把對(duì)象說明想象成一個(gè)可選的接口,把對(duì)象體想象成一個(gè)黒盒。我們可以在不改變說明局部的前提下調(diào)試,增強(qiáng)或替換對(duì)象體,并
7、且不會(huì)對(duì)客戶端程序造成影響。 在一個(gè)對(duì)象說明中,所有的屬性都必須聲明在方法之前。只有子程序的聲明才需要實(shí)現(xiàn)。所以,如果一個(gè)對(duì)象類型的說明只聲明了屬性,那么對(duì)象類型的體就沒有必要了。我們不能在對(duì)象體中聲明屬性。對(duì)象說明中的聲明都是公有的。 為了能更好的了解結(jié)構(gòu),請(qǐng)看下面的例子。這是一個(gè)復(fù)數(shù)的對(duì)象類型,有實(shí)數(shù)局部和虛數(shù)局部,并有幾個(gè)與復(fù)數(shù)操作相關(guān)的方法。 CREATE TYPE complex AS OBJECT( rpart REAL, - attribut
8、e ipart REAL, MEMBER FUNCTION plus(x complex) RETURN complex, - method MEMBER FUNCTION LESS(x complex) RETURN complex, MEMBER
9、FUNCTION times(x complex) RETURN complex, MEMBER FUNCTION divby(x complex) RETURN complex);CREATE TYPE BODY complex AS MEMBER FUNCTION plus(x complex)
10、 RETURN complex IS BEGIN RETURN complex(rpart + x.rpart, ipart + x.ipart); END plus; MEMBER FUNCTION LESS(x complex) RETURN complex IS
11、 BEGIN RETURN complex(rpart - x.rpart, ipart - x.ipart); END LESS; MEMBER FUNCTION times(x complex) RETURN complex IS BEGIN RETURN
12、60;complex(rpart * x.rpart - ipart * x.ipart, rpart * x.ipart + ipart * x.rpart); END times; MEMBER&
13、#160;FUNCTION divby(x complex) RETURN complex IS z REAL := x.rpart * 2 + x.ipart * 2; BEGIN RETURN complex(rpart * x.rpart
14、+ ipart * x.ipart) / z, (ipart * x.rpart - rpart * x.ipart) / z); END divby;END; 五、對(duì)象類型組件對(duì)象類型封裝了數(shù)據(jù)和操作。我們可以
15、在對(duì)象類型說明中聲明屬性和方法,但不能聲明常量、異常、游標(biāo)或類型。我們至少要聲明一個(gè)屬性(最多1000個(gè)),方法是可選的。 1、屬性同變量一樣,屬性也有名稱和數(shù)據(jù)類型。對(duì)象類型中的名稱必須是唯一的(但在其他的對(duì)象類型中可以重用)。除了下面幾種類型之外,其他任何Oralce類型都可以使用: 1. LONG和LONG RAW 2. ROWID和UROWID 3. PL/SQL特定類型BINARY_INTEGER及它的子類型、BOOLEAN、PLS_INTEGER、RECORD、REF CURSOR、%TYPE和%ROWTYPE 4. PL/SQL包內(nèi)定義的數(shù)據(jù)類型 我們不能在聲明屬性的時(shí)候用賦值語
16、句或DEFAULT子句為它初始化。同樣,也不能對(duì)屬性應(yīng)用NOT NULL約束。但是,對(duì)象是可以存放到添加了約束的數(shù)據(jù)表中。 數(shù)據(jù)結(jié)構(gòu)中的屬性集合依賴于真實(shí)世界中的對(duì)象。例如,為了表現(xiàn)一個(gè)分?jǐn)?shù),我們只需要兩個(gè)INTEGER類型的變量。另一方面,要是表現(xiàn)一個(gè)學(xué)生,我們需要幾個(gè)VARCHAR2來存放姓名、住址、 號(hào)碼和狀態(tài)等,再添加一個(gè)VARRAY類型變量用來存儲(chǔ)課程和分?jǐn)?shù)。 數(shù)據(jù)結(jié)構(gòu)可能是復(fù)雜的。例如,一個(gè)屬性的數(shù)據(jù)類型可能是另外一個(gè)對(duì)象類型(稱為嵌套對(duì)象類型)。有些對(duì)象類型,像隊(duì)列、鏈表和樹,都是動(dòng)態(tài)的,它們是隨著使用的需要而動(dòng)態(tài)改變存儲(chǔ)長度的。遞歸對(duì)象類型能夠直接或間接的包含自身類型,這樣就能
17、創(chuàng)立出更詭異的數(shù)據(jù)類型。 2、方法一般的,方法就是用關(guān)鍵字MEMBER或STATIC聲明在對(duì)象說明局部的子程序。方法名不能和對(duì)象類型名、屬性名重復(fù)。MEMBER方法只能通過對(duì)象實(shí)例調(diào)用,如: instance_expression.method() 但是,STATIC方法直接通過對(duì)象類型調(diào)用,而不是實(shí)例,如:object_type_name.method() 方法的定義規(guī)那么與打包子程序的相同,也分為說明和體兩個(gè)局部。說明局部由一個(gè)方法名和一個(gè)可選的參數(shù)列表組成,如果是函數(shù),還需要包含一個(gè)返回類型。包體就是一段能執(zhí)行一個(gè)特殊任務(wù)的代碼。對(duì)于對(duì)象類型說明中的每個(gè)方法說明,在對(duì)象類型體中都必須有與
18、之對(duì)應(yīng)的方法體實(shí)現(xiàn),除非這個(gè)方法是用關(guān)鍵字NOT INSTANTIABLE加以限定,它的意思就是方法體的實(shí)現(xiàn)只在子類中出現(xiàn)。為了使方法說明和方法體相匹配,PL/SQL編譯器采用token-by- token的方式把它們的頭部進(jìn)行比較。頭部必須精確匹配。與屬性相同,一個(gè)形式參數(shù)的聲明也是由名稱和數(shù)據(jù)類型組成。但是,參數(shù)的類型不能受到大小約束。數(shù)據(jù)的類型可以是任何Oracle類型,除了那些不適用于屬性的類型。這些約束也適用于返回值的類型。· 方法實(shí)現(xiàn)所允許使用的語言 Oracle允許我們?cè)赑L/SQL、Java或C語言中實(shí)現(xiàn)對(duì)象方法。我們可以在Java或C語言中實(shí)現(xiàn)類型方法,只需提供一個(gè)
19、調(diào)用說明即可。調(diào)用說明在Oracle的數(shù)據(jù)詞典中公布了Java方法或外部C函數(shù)。它把程序的名稱、參數(shù)類型和返回值信息映射到對(duì)應(yīng)的SQL中去。 · SELF參數(shù) MEMBER方法接受一個(gè)內(nèi)置的SELF參數(shù),它代表了對(duì)象類型的實(shí)例。不管顯式或隱式聲明,它總是第一個(gè)傳入MEMBER方法的參數(shù)。但是,STATIC方法就不能接受或引用SELF。 在方法體中,SELF指定了被調(diào)用方法所屬的對(duì)象實(shí)例。例如,方法transform把SELF聲明為IN OUT參數(shù): CREATE TYPE Complex AS OBJECT (
20、MEMBER FUNCTION transform (SELF IN OUT Complex) . 我們不能把SELF指定成其他數(shù)據(jù)類型。在MEMBER函數(shù)中,如果SELF沒有聲明的話,它的參數(shù)默認(rèn)為IN。但是,在MEMBER過程中,如果SELF沒有什么,那么它的參數(shù)模式默認(rèn)為IN OUT。并且,我們不能把SELF的模式指定為OUT。 如下例所示,方法可以直接引用SELF的屬性,并不需要限定修飾詞: CREATE FUNCTION gcd(x INTEGER, y INTEG
21、ER) RETURN INTEGER AS - find greatest common divisor of x and y ans INTEGER;BEGIN IF (y <= x) AND(x MOD y = 0) THEN an
22、s := y; ELSIF x < y THEN ans := gcd(y, x); ELSE ans := gcd(y, x MOD y); END IF;
23、0;RETURN ans;END;CREATE TYPE rational AS OBJECT( num INTEGER, den INTEGER, MEMBER PROCEDURE normalize, .);CREATE TYPE BODY rational AS MEMBER PROCEDURE
24、 normalize IS g INTEGER; BEGIN g := gcd(SELF.num, SELF.den); g := gcd(num, den); -
25、0;equivalent to previous statement num := num / g; den := den / g; END normalize; .END; 如果我們從SQL語句中調(diào)用了一個(gè)空實(shí)例(即SELF為空)的MEMBER方法,方法不會(huì)被調(diào)用,并且
26、會(huì)返回一個(gè)空值。如果從過程語句調(diào)用的話,PL/SQL就會(huì)拋出預(yù)定義異常SELEF_IS_NULL。 · 重載 與打包子程序一樣,同種類型的方法(函數(shù)或過程)都能被重載。也就是說,我們可以為不同的方法起相同的名字,只要它們的形式參數(shù)在數(shù)量、順序或數(shù)據(jù)類型上有所不同。當(dāng)我們調(diào)用其中一個(gè)方法的時(shí)候,PL/SQL會(huì)把實(shí)參列表和形參列表作比較,然后找出適宜的方法。子類型也可以重載它的基類方法。這種情況下,方法必須有完全相同的形式參數(shù)。如果兩個(gè)方法只是在參數(shù)模式上不同的話,我們是不能進(jìn)行重載操作的。并且,我們不能因兩個(gè)函數(shù)的返回值類型不同而對(duì)它們進(jìn)行重載。· MAP和ORDER方法 一
27、個(gè)標(biāo)量類型,如CHAR或REAL的值都有一個(gè)預(yù)定義的順序,這樣它們之間就能進(jìn)行比較。但是對(duì)象類型的實(shí)例沒有預(yù)定義的順序。要想對(duì)它們進(jìn)行比較或排序就要調(diào)用我們自己實(shí)現(xiàn)的MAP函數(shù)。在下面的例子中,關(guān)鍵字MAP指明了方法convert()通過把Relational對(duì)象影射到REAL型上,來對(duì)它們進(jìn)行排序操作:CREATE TYPE rational AS OBJECT( num INTEGER, den INTEGER, MA
28、P MEMBER FUNCTION CONVERT RETURN REAL, .);CREATE TYPE BODY rational AS MAP MEMBER FUNCTION CONVERT RETURN REAL IS BEGIN RETURN n
29、um / den; END CONVERT; .END; PL/SQL使用順序來計(jì)算布爾表達(dá)式的值,如x < y,并且可以在DISTINCT,GROUP BY和ORDER BY子句中作比較。MAP方法convert()可以返回一個(gè)對(duì)象在所有Relation對(duì)象中的相對(duì)位置。一個(gè)對(duì)象類型只能包含一個(gè)MAP方法,它接受一個(gè)內(nèi)置參數(shù)SELF并返回一個(gè)標(biāo)量類型:DATE、NUMBER、VARCHAR2,或是一個(gè)ANSI SQL類型,如CHARACTER或REAL。另外,我們還可以用ORDER方法。一個(gè)對(duì)象類型只能有一個(gè)OR
30、DER方法,它必須是一個(gè)能返回?cái)?shù)字結(jié)果的函數(shù)。在下面的例子中,關(guān)鍵字ORDER說明了方法match()可以對(duì)兩個(gè)對(duì)象進(jìn)行比較操作:CREATE TYPE customer AS OBJECT( ID NUMBER, NAME VARCHAR2(20), addr VARCHAR2(30), ORDER MEMBER FUNC
31、TION match(c customer) RETURN INTEGER);CREATE TYPE BODY customer AS ORDER MEMBER FUNCTION match(c customer) RETURN INTEGER IS BEGIN IF ID
32、160;< c.ID THEN RETURN -1; - any negative number will do ELSIF ID > c.ID THEN RETURN 1; - any
33、0;positive number will do ELSE RETURN 0; END IF; END;END; 每個(gè)ORDER方法都只能接受兩個(gè)參數(shù):內(nèi)置參數(shù)SELF和另外一個(gè)同類型的對(duì)象。如果c1和c2是Customer對(duì)象,一個(gè)c1 > c2這樣的比較就會(huì)自動(dòng)調(diào)用方法match。該方法能夠返回負(fù)數(shù)、零或正數(shù),分別代表SELF比另外一個(gè)對(duì)象小、等或大。
34、如果傳到ORDER方法的參數(shù)任意一個(gè)為空,方法就會(huì)返回空值。知道方針:一個(gè)MAP方法就好比一個(gè)哈希函數(shù),能把對(duì)象值影射到標(biāo)量值,然后用操作符,如<、=等來進(jìn)行比較。一個(gè)ORDER方法只是簡單地將兩個(gè)對(duì)象進(jìn)行比較。我們可以聲明一個(gè)MAP方法或是一個(gè)ORDER方法,但不同時(shí)聲明這兩個(gè)方法。如果我們聲明了其中一個(gè),我們就可以在SQL或過程語句中進(jìn)行對(duì)象比較。但是,如果我們沒有聲明方法,我們就只能在SQL語句中進(jìn)行等或不等的比較。(兩個(gè)同類型的對(duì)象只有它們對(duì)應(yīng)的屬性值相同的時(shí)候才相等。)在對(duì)大量的對(duì)象進(jìn)行排序或合并的時(shí)候,可以使用一個(gè)MAP方法。一次調(diào)用會(huì)把所有的對(duì)象影射到標(biāo)量中,然后對(duì)標(biāo)量值進(jìn)
35、行排序。ORDER方法的效率相比照擬低,因?yàn)樗仨毞磸?fù)地調(diào)用(它一次只能比較兩個(gè)對(duì)象)。· 構(gòu)造方法 每個(gè)對(duì)象類型都有一個(gè)構(gòu)造方法,它是一個(gè)名稱與對(duì)象類型名稱相同的函數(shù),用于初始化,并能返回一個(gè)對(duì)象類型的新的實(shí)例。Oracle會(huì)為每個(gè)對(duì)象類型生成一個(gè)構(gòu)造函數(shù),其中形參與對(duì)象類型的屬性相匹配。也就是說,參數(shù)和屬性是一一對(duì)應(yīng)的關(guān)系,并且順序、名稱和數(shù)據(jù)類型都完全相同。我們也可以定義自己的構(gòu)造方法,要么覆蓋掉系統(tǒng)定義的構(gòu)造函數(shù),要么定義一個(gè)有著不同方法簽名的新構(gòu)造函數(shù)。PL/SQL從來不會(huì)隱式地調(diào)用構(gòu)造函數(shù),所以我們必須顯式地調(diào)用它。3、更改已存在對(duì)象類型的屬性和方法我們可以使用ALTER
36、 TYPE語句來添加、修改或刪除屬性,并可以為已存在的對(duì)象類型添加或刪除方法: CREATE TYPE person_typ AS OBJECT( NAME CHAR(20), ssn CHAR(12), address VARCHAR2(100);CREATE TYPE person_
37、nt IS TABLE OF person_typ;CREATE TYPE dept_typ AS OBJECT( mgr person_typ, emps person_nt);CREATE TABLE dept OF dept_typ;- Add new attributes to Per
38、son_typ and propagate the change- to Person_nt and dept_typALTER TYPE person_typ ADD ATTRIBUTE (picture BLOB, dob DATE) CASCADE NOT INCLUDING TABLE DATA;CREATE TYPE mytype
39、160;AS OBJECT( attr1 NUMBER, attr2 NUMBER);ALTER TYPE mytype ADD ATTRIBUTE (attr3 NUMBER), DROP ATTRIBUTE attr2, ADD ATTRIBUTE attr4 NUMBER CASCADE; 在過
40、程編譯時(shí),它總是使用當(dāng)前引用的對(duì)象類型版本。在對(duì)象類型發(fā)生改變時(shí),效勞器端引用那個(gè)對(duì)象類型的過程就變得無效了,在下次過程被調(diào)用時(shí)它會(huì)被自動(dòng)重新編譯。而對(duì)于客戶端引用被更改正的類型的過程,我們就必須手動(dòng)編譯。 如果從基類刪除一個(gè)方法,那么也必須修改覆蓋被刪除方法的子類。我們可以用ALTER TYPE的CASADE選擇來判斷是否有子類被影響到;如果有子類覆蓋了方法,那么語句就會(huì)被回滾。為了能成功地從基類刪除一個(gè)方法,我們可以: 1. 先從子類刪除方法 2. 從基類刪除方法,然后用不帶OVERRIDING關(guān)鍵字的ALTER TYPE把它重新添加進(jìn)去 六、定義對(duì)象類型對(duì)象類型可以表現(xiàn)現(xiàn)實(shí)世界中的任何實(shí)
41、體。例如,一個(gè)對(duì)象類型能表現(xiàn)學(xué)生,銀行賬戶,計(jì)算機(jī)顯示器,有理數(shù)或者是像隊(duì)列,棧,鏈表這樣的數(shù)據(jù)結(jié)構(gòu)。這一節(jié)給出了幾個(gè)完整的例子,讓我們了解如何設(shè)計(jì)對(duì)象類型并編寫我們自己的對(duì)象類型。目前我們還不能在PL/SQL塊、子程序或包中定義對(duì)象類型。但是,我們可以在SQL*Plus中用下面的語法來定義它: CREATE OR REPLACE TYPE type_name AUTHID CURRENT_USER | DEFINER IS | AS OB
42、JECT | UNDER supertype_name ( attribute_name datatype, attribute_name datatype. MAP | ORDER MEMBER function_spec, FINAL| NOT FINAL MEMBER function_spec, INSTANTIABLE| NOT
43、INSTANTIABLE MEMBER function_spec, MEMBER | STATIC subprogram_spec | call_spec , MEMBER | STATIC subprogram_spec | call_spec.) FINAL| NOT FINAL INSTANTIABLE| NOT INSTANTIABLE;CR
44、EATE OR REPLACE TYPE BODY type_name IS | AS MAP | ORDER MEMBER function_body; | MEMBER | STATIC subprogram_body | call_spec; MEMBER | STATIC subprogram_body
45、 | call_spec;.END; 1、PL/SQL類型繼承一覽PL/SQL支持單繼承模式。我們可以定義對(duì)象類型的子類型。這些子類型包括父類型(或超類)所有的屬性和方法。子類型還可以包括額外的屬性和方法,并可以覆蓋超類的方法。 我們還可以定義子類是否能繼承于某個(gè)特定的類型。我們也可以定義不能直接初始化的類型和方法,只有聲明它們的子類才可以進(jìn)行初始化操作。 有些類型屬性可以用ALTER TYPE語句動(dòng)態(tài)的改變。當(dāng)基類發(fā)生變化時(shí),無論是用ALTER TYPE語句還是重新定義基類,子類會(huì)自動(dòng)的應(yīng)用這些改變的內(nèi)容。我們可以用TREAT操作符只返回某一個(gè)指定的子類的對(duì)象。 從REF
46、和DEREF函數(shù)中產(chǎn)生的值可以代表聲明過的表或視圖類型,或是一個(gè)或多個(gè)它的子類型。 · PL/SQL類繼承舉例 - Create a supertype from which several subtypes will be derived.CREATE TYPE person_typ AS OBJECT( ssn NUMBER, &
47、#160;NAME VARCHAR2(30), address VARCHAR2(100)NOT FINAL;- Derive a subtype that has all the attributes of the supertype,- plus some additional attributes.CREA
48、TE TYPE student_typ UNDER person_typ( deptid NUMBER, major VARCHAR2(30)NOT FINAL;- Because Student_typ is declared NOT FINAL, you can derive- further subtypes
49、 from it.CREATE TYPE parttimestudent_typ UNDER student_typ( numhours NUMBER);- Derive another subtype. Because it has the default attribute- FINAL, you cannot use Employee_
50、typ as a supertype and derive- subtypes from it.CREATE TYPE employee_typ UNDER person_typ( empid NUMBER, mgr VARCHAR2(30);- Define an object type t
51、hat can be a supertype. Because the- member function is FINAL, it cannot be overridden in any- subtypes.CREATE TYPE T AS OBJECT (., MEMBER PROCEDURE Print(), FINAL M
52、EMBERFUNCTION foo(x NUMBER).) NOT FINAL;- We never want to create an object of this supertype. By using- NOT INSTANTIABLE, we force all objects to use one of the
53、0;subtypes- instead, with specific implementations for the member functions.CREATE TYPE Address_typ AS OBJECT(.) NOT INSTANTIABLE NOT FINAL;- These subtypes can provide their own implem
54、entations of- member functions, such as for validating phone numbers and- postal codes. Because there is no "generic" way of doing these- things, only objects of
55、0;these subtypes can be instantiated.CREATE TYPE USAddress_typ UNDER Address_typ(.);CREATE TYPE IntlAddress_typ UNDER Address_typ(.);- Return REFs for those Person_typ objects that are instances&
56、#160;of- the Student_typ subtype, and NULL REFs otherwise.SELECT TREAT(REF(p) AS REF student_typ) FROM person_v p;- Example of using TREAT for assignment.- Return REFs for th
57、ose Person_type objects that are instances of- Employee_type or Student_typ, or any of their subtypes.SELECT REF(p) FROM person_v p WHERE VALUE(p) IS OF(employee_typ, student_typ)
58、;- Similar to above, but do not allow any subtypes of Student_typ.SELECT REF(p) FROM person_v p WHERE VALUE(p) IS OF(ONLY student_typ);- The results of REF and DERE
59、F can include objects of Person_typ- and its subtypes such as Employee_typ and Student_typ.SELECT REF(p) FROM person_v p;SELECT DEREF(REF(p) FROM person_v p; 2、對(duì)象類型實(shí)例:棧棧是一個(gè)有序集合。棧有一個(gè)棧頂
60、和一個(gè)棧底。棧中的每一項(xiàng)都只能在棧頂添加或刪除。所以,最后一個(gè)被參加棧的項(xiàng)會(huì)被最先刪除。(可以把棧想象成自助餐廳中的盤子。)壓棧和退棧操作能夠?qū)_M(jìn)行后進(jìn)先出(LIFO)更新。 棧能應(yīng)用在很多地方。例如,它們可以用在系統(tǒng)編程中控制中斷優(yōu)先級(jí)并對(duì)遞歸進(jìn)行管理。最簡單的棧實(shí)現(xiàn)就是使用整數(shù)數(shù)組,數(shù)組的一端代表了棧頂。 PL/SQL提供了VARRAY數(shù)據(jù)類型,它能讓我們聲明變長數(shù)組。要聲明變長數(shù)組屬性,必須先定義變長數(shù)組類型。但是,我們不能再對(duì)象說明中定義類型,所以,我們只能單獨(dú)的定義變長數(shù)組類型,并指定它的最大長度,具體實(shí)現(xiàn)如下: CREATE TYPE IntArray
61、0;AS VARRAY(25) OF INTEGER; 現(xiàn)在我們可以編寫對(duì)象類型說明了:CREATE TYPE stack AS OBJECT( max_size INTEGER, top INTEGER, POSITION intarray, MEMBER PROCE
62、DURE initialize, MEMBER FUNCTION FULL RETURN BOOLEAN, MEMBER FUNCTION empty RETURN BOOLEAN, MEMBER PROCEDURE push(n IN INTEGER), MEMBER PROCEDURE
63、;pop(n OUT INTEGER); 最后,我們可以編寫對(duì)象類型體:CREATE TYPE BODY stack AS MEMBER PROCEDURE initialize IS BEGIN top := 0; /* Call co
64、nstructor for varray and set element 1 to NULL. */ POSITION := intarray(NULL); max_size := POSITION.LIMIT; - get varray s
65、ize constraint POSITION.EXTEND(max_size - 1, 1); - copy element 1 into 2.25 END initialize; MEMBER FUNCTION FULL RETURN BOOLEAN IS BEG
66、IN RETURN(top = max_size); - return TRUE if stack is full END FULL; MEMBER FUNCTION empty RETURN BOOLEAN IS BEGIN RE
67、TURN(top = 0); - return TRUE if stack is empty END empty; MEMBER PROCEDURE push(n IN INTEGER) IS BEGIN IF NOT FULL THEN
68、; top := top + 1; - push integer onto stack POSITION(top) := n; ELSE
69、 - stack is full raise_application_error(-20211, 'stack overflow'); END IF; END push; MEMBER PROCEDURE pop(n OUT INTEGER) IS
70、;BEGIN IF NOT empty THEN n := POSITION(top); top := top - 1; - pop integer off
71、0;stack ELSE - stack is empty raise_application_error(-20212, 'stack underflow'); END IF; END pop;END; 在成員過程push和pop中,我們使用內(nèi)置過程rais
72、e_application_error來關(guān)聯(lián)用戶定義的錯(cuò)誤消息。這樣,我們就能把錯(cuò)誤報(bào)告給客戶端程序而防止把未控制異常傳給主環(huán)境。客戶端程序捕獲PL/SQL異常后,可以在OTHERS異常控制句柄中用SQLCODE和SQLERRM 來確定具體的錯(cuò)誤信息。下例中,當(dāng)異常被拋出時(shí),我們就把對(duì)應(yīng)的錯(cuò)誤消息輸出: DECLARE .BEGIN .EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLERRM);END; 另外,
73、程序還可以使用編譯指示EXCEPTION_INIT把raise_application_error返回的錯(cuò)誤編號(hào)影射到命名異常中,如下例所示:DECLARE stack_overflow EXCEPTION; stack_underflow EXCEPTION; PRAGMA EXCEPTION_INIT(stack_overflow, -20211); PRAGMA EXCEPTION_INIT(
74、stack_underflow, -20212);BEGIN .EXCEPTION WHEN stack_overflow THEN .END; 3、對(duì)象類型實(shí)例:售票處假設(shè)有一個(gè)連鎖電影院,每個(gè)影院有三個(gè)銀幕。每個(gè)影院有一個(gè)售票處,銷售三種不同電影的影票。所有影票的價(jià)格都為三美元。定期檢查影票的銷售情況,然后及時(shí)補(bǔ)充影票。 在定義代表銷售處的對(duì)象類型之前,我們必須考慮到必要的數(shù)據(jù)和操作。對(duì)于一個(gè)簡單的售票處來說,對(duì)象類型需要票價(jià)、當(dāng)前影票存量和已售影票的收據(jù)這些屬性。它還需要一些方法:購票、盤存、
75、補(bǔ)充存量和收集收據(jù)。 對(duì)于收據(jù),我們可以使用含有三個(gè)元素的數(shù)組。元素1、2和3各自記錄電影1、2和3。要聲明一個(gè)變長數(shù)組屬性,我們就必須先像下面這樣定義它的類型: CREATE TYPE RealArray AS VARRAY(3) OF REAL; 現(xiàn)在,我們可以編寫對(duì)象類型說明: CREATE TYPE ticket_booth AS OBJECT( price R
76、EAL, qty_on_hand INTEGER, receipts realarray, MEMBER PROCEDURE initialize, MEMBER PROCEDURE purchase(movie INTEGER, amount REAL, CHANGE OUT REAL),
77、160;MEMBER FUNCTION inventory RETURN INTEGER, MEMBER PROCEDURE replenish(quantity INTEGER), MEMBER PROCEDURE COLLECT(movie INTEGER, amount OUT REAL); 最后,我們可以編寫對(duì)象類型體: CREATE TYPE BODY
78、60;ticket_booth AS MEMBER PROCEDURE initialize IS BEGIN price := 3.00; qty_on_hand := 5000; - prov
79、ide initial stock of tickets - call constructor for varray and set elements 1.3 to zero receipts := realarray(0, 0, 0);
80、60;END initialize; MEMBER PROCEDURE purchase(movie INTEGER, amount REAL, CHANGE OUT REAL) IS BEGIN IF qty_on_hand = 0 THEN raise_application_error(-20
81、213, 'out of stock'); END IF; IF amount >= price THEN qty_on_hand := qty_on_hand - 1;
82、60; receipts(movie) := receipts(movie) + price; CHANGE := amount - price; ELSE -
83、0;amount is not enough CHANGE := amount; - so return full amount END IF; END purchase; MEMBER FUNCTION inventory
84、160; RETURN INTEGER IS BEGIN RETURN qty_on_hand; END inventory; MEMBER PROCEDURE replenish(quantity INTEGER) IS BEGIN qty_on_hand :=
85、0;qty_on_hand + quantity; END replenish; MEMBER PROCEDURE COLLECT(movie INTEGER, amount OUT REAL) IS BEGIN amount :=&
86、#160;receipts(movie); - get receipts for a given movie receipts(movie) := 0; - reset receipts to zero END COLLECT;END; 4、對(duì)象類型實(shí)例:銀行賬戶在定義銀行賬戶對(duì)象類型之前,我們必
87、須考慮一下要使用的數(shù)據(jù)和操作。對(duì)于一個(gè)簡單的銀行賬戶來說,對(duì)象類型需要一個(gè)賬號(hào)、余額和狀態(tài)這三個(gè)屬性。所需的操作有:翻開帳戶,驗(yàn)證賬號(hào),關(guān)閉賬戶,存款,取款和余額結(jié)算。首先,我們要像下面這樣編寫對(duì)象類型說明: CREATE TYPE bank_account AS OBJECT( acct_number INTEGER(5), balance REAL, status
88、0; VARCHAR2(10), MEMBER PROCEDURE OPEN(amount IN REAL), MEMBER PROCEDURE verify_acct(num IN INTEGER), MEMBER PROCEDURE CLOSE(num IN INTEGER, amount OUT
89、;REAL), MEMBER PROCEDURE deposit(num IN INTEGER, amount IN REAL), MEMBER PROCEDURE withdraw(num IN INTEGER, amount IN REAL), MEMBER FUNCTION curr_bal(num IN INTEGER)
90、 RETURN REAL); 然后編寫對(duì)象體: CREATE TYPE BODY bank_account AS MEMBER PROCEDURE OPEN(amount IN REAL) IS - open account with initial deposit BEGIN IF NOT a
91、mount > 0 THEN raise_application_error(-20214, 'bad amount'); END IF; SELECT acct_sequence.NEXTVAL INTO acct_number
92、 FROM DUAL; status := 'open' balance := amount; END OPEN; MEMBER PROCEDURE verify_acct(num IN INTEGER) IS
93、; - check for wrong account number or closed account BEGIN IF (num <> acct_number) THEN raise_application_error(-20215, 'wrong number'); ELSIF(status = 'closed') THEN ra
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度國際貨物貿(mào)易風(fēng)險(xiǎn)管理合同范本
- 二零二四年配電柜接線外包工程進(jìn)度及結(jié)算合同模板3篇
- 二零二四年度2024年水果銷售代理合同范本3篇
- 2025版稅務(wù)籌劃與審計(jì)代理服務(wù)合同范本3篇
- 2025年度戶外廣告牌拆除與戶外廣告企業(yè)信用管理合同
- 2025年適用股權(quán)轉(zhuǎn)讓合同模板及工商變更登記流程指南
- 2025年度物流運(yùn)輸擔(dān)保合同標(biāo)的貨物安全運(yùn)輸協(xié)議
- 2025版水利工程建筑工程質(zhì)量監(jiān)督檢驗(yàn)合同3篇
- 2025年度國際工程建設(shè)項(xiàng)目合同規(guī)范文本
- 2025年度智能交通控制系統(tǒng)合同樣本
- (一模)蕪湖市2024-2025學(xué)年度第一學(xué)期中學(xué)教學(xué)質(zhì)量監(jiān)控 英語試卷(含答案)
- 完整版秸稈炭化成型綜合利用項(xiàng)目可行性研究報(bào)告
- 2025中國海油春季校園招聘1900人高頻重點(diǎn)提升(共500題)附帶答案詳解
- 膽汁淤積性肝硬化護(hù)理
- 《數(shù)據(jù)采集技術(shù)》課件-Scrapy 框架的基本操作
- (2024)河南省公務(wù)員考試《行測》真題及答案解析
- 醫(yī)療保險(xiǎn)結(jié)算與審核制度
- 2024版房屋市政工程生產(chǎn)安全重大事故隱患判定標(biāo)準(zhǔn)內(nèi)容解讀
- 醫(yī)院投訴糾紛及處理記錄表
- YY/T 0698.5-2023最終滅菌醫(yī)療器械包裝材料第5部分:透氣材料與塑料膜組成的可密封組合袋和卷材要求和試驗(yàn)方法
- 【深度教學(xué)研究國內(nèi)外文獻(xiàn)綜述2100字】
評(píng)論
0/150
提交評(píng)論