軟件工程:第9章 數(shù)據(jù)庫及其接口設(shè)計(jì)實(shí)現(xiàn)_第1頁
軟件工程:第9章 數(shù)據(jù)庫及其接口設(shè)計(jì)實(shí)現(xiàn)_第2頁
軟件工程:第9章 數(shù)據(jù)庫及其接口設(shè)計(jì)實(shí)現(xiàn)_第3頁
軟件工程:第9章 數(shù)據(jù)庫及其接口設(shè)計(jì)實(shí)現(xiàn)_第4頁
軟件工程:第9章 數(shù)據(jù)庫及其接口設(shè)計(jì)實(shí)現(xiàn)_第5頁
已閱讀5頁,還剩126頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院1第9章數(shù)據(jù)庫及其接口設(shè)計(jì)實(shí)現(xiàn)9.1數(shù)據(jù)庫概念結(jié)構(gòu)設(shè)計(jì)9.2數(shù)據(jù)庫邏輯結(jié)構(gòu)設(shè)計(jì)2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院29.1數(shù)據(jù)庫概念結(jié)構(gòu)設(shè)計(jì)什么是概念結(jié)構(gòu)設(shè)計(jì)需求分析階段描述的用戶應(yīng)用需求是現(xiàn)實(shí)世界的具體需求將需求分析得到的用戶需求抽象為信息結(jié)構(gòu)即概念模型的過程就是概念結(jié)構(gòu)設(shè)計(jì)概念結(jié)構(gòu)是各種數(shù)據(jù)模型的共同基礎(chǔ),它比數(shù)據(jù)模型更獨(dú)立于機(jī)器、更抽象,從而更加穩(wěn)定。概念結(jié)構(gòu)設(shè)計(jì)是整個(gè)數(shù)據(jù)庫設(shè)計(jì)的關(guān)鍵AnIntroductiontoDatabaseSystem3/92概念結(jié)構(gòu)(續(xù))**描述概念模型的工具E-R模型一、數(shù)據(jù)抽象二、局部視圖設(shè)計(jì)三、視圖集成AnIntroductiontoDatabaseSystem4/92數(shù)據(jù)抽象三種常用抽象1.分類(Classification)定義某一類概念作為現(xiàn)實(shí)世界中一組對象的類型這些對象具有某些共同的特性和行為它抽象了對象值和型之間的“ismemberof”的語義在E-R模型中,實(shí)體型就是這種抽象AnIntroductiontoDatabaseSystem5/92數(shù)據(jù)抽象(續(xù))AnIntroductiontoDatabaseSystem6/92數(shù)據(jù)抽象(續(xù))2.聚集(Aggregation)定義某一類型的組成成分它抽象了對象內(nèi)部類型和成分之間“ispartof”的語義在E-R模型中若干屬性的聚集組成了實(shí)體型,就是這種抽象AnIntroductiontoDatabaseSystem7/92數(shù)據(jù)抽象(續(xù))聚集8/92數(shù)據(jù)抽象(續(xù))

復(fù)雜的聚集,某一類型的成分仍是一個(gè)聚集更復(fù)雜的聚集9/92數(shù)據(jù)抽象(續(xù))3.概括(Generalization)定義類型之間的一種子集聯(lián)系它抽象了類型之間的“issubsetof”的語義概括有一個(gè)很重要的性質(zhì):繼承性。子類繼承超類上定義的所有抽象。10/92數(shù)據(jù)抽象(續(xù))AnIntroductiontoDatabaseSystem11/92局部視圖設(shè)計(jì)注:原E-R模型不具有概括,本書對E-R模型作了擴(kuò)充,允許定義超類實(shí)體型和子類實(shí)體型。

用雙豎邊的矩形框表示子類,用直線加小圓圈表示超類-子類的聯(lián)系設(shè)計(jì)分E-R圖的步驟:⒈選擇局部應(yīng)用⒉逐一設(shè)計(jì)分E-R圖AnIntroductiontoDatabaseSystem12/92⒈選擇局部應(yīng)用需求分析階段,已用多層數(shù)據(jù)流圖和數(shù)據(jù)字典描述了整個(gè)系統(tǒng)。設(shè)計(jì)分E-R圖首先需要根據(jù)系統(tǒng)的具體情況,在多層的數(shù)據(jù)流圖中選擇一個(gè)適當(dāng)層次的數(shù)據(jù)流圖,讓這組圖中每一部分對應(yīng)一個(gè)局部應(yīng)用,然后以這一層次的數(shù)據(jù)流圖為出發(fā)點(diǎn),設(shè)計(jì)分E-R圖。AnIntroductiontoDatabaseSystem13/92選擇局部應(yīng)用(續(xù))**通常以中層數(shù)據(jù)流圖作為設(shè)計(jì)分E-R圖的依據(jù)。原因:高層數(shù)據(jù)流圖只能反映系統(tǒng)的概貌中層數(shù)據(jù)流圖能較好地反映系統(tǒng)中各局部應(yīng)用的子系統(tǒng)組成低層數(shù)據(jù)流圖過細(xì)AnIntroductiontoDatabaseSystem14/92選擇局部應(yīng)用(續(xù))例:由于學(xué)籍管理、課程管理等都不太復(fù)雜,因此可以它們?nèi)胧衷O(shè)計(jì)學(xué)生管理子系統(tǒng)的分E-R圖。如果局部應(yīng)用比較復(fù)雜,則可以從更下層的數(shù)據(jù)流圖入手。AnIntroductiontoDatabaseSystem15/92選擇局部應(yīng)用(續(xù))設(shè)計(jì)分E-R圖的出發(fā)點(diǎn)16/92⒉逐一設(shè)計(jì)分E-R圖任務(wù)標(biāo)定局部應(yīng)用中的實(shí)體、屬性、碼,實(shí)體間的聯(lián)系將各局部應(yīng)用涉及的數(shù)據(jù)分別從數(shù)據(jù)字典中抽取出來,參照數(shù)據(jù)流圖,標(biāo)定各局部應(yīng)用中的實(shí)體、實(shí)體的屬性、標(biāo)識(shí)實(shí)體的碼確定實(shí)體之間的聯(lián)系及其類型(1:1,1:n,m:n)17/92逐一設(shè)計(jì)分E-R圖(續(xù))兩條準(zhǔn)則:(1)屬性不能再具有需要描述的性質(zhì)。即屬性必須是不可分的數(shù)據(jù)項(xiàng),不能再由另一些屬性組成(2)屬性不能與其他實(shí)體具有聯(lián)系。聯(lián)系只發(fā)生在實(shí)體之間符合上述兩條特性的事物一般作為屬性對待。為了簡化E-R圖的處置,現(xiàn)實(shí)世界中的事物凡能夠作為屬性對待的,應(yīng)盡量作為屬性。18/92逐一設(shè)計(jì)分E-R圖(續(xù))職稱作為一個(gè)實(shí)體19/92逐一設(shè)計(jì)分E-R圖(續(xù))病房作為一個(gè)實(shí)體20/92逐一設(shè)計(jì)分E-R圖(續(xù))倉庫作為一個(gè)實(shí)體21/92逐一設(shè)計(jì)分E-R圖(續(xù))[實(shí)例]銷售管理子系統(tǒng)分E-R圖的設(shè)計(jì)銷售管理子系統(tǒng)的主要功能:處理顧客和銷售員送來的訂單工廠是根據(jù)訂貨安排生產(chǎn)的交出貨物同時(shí)開出發(fā)票收到顧客付款后,根據(jù)發(fā)票存根和信貸情況進(jìn)行應(yīng)收款處理22/92逐一設(shè)計(jì)分E-R圖(續(xù))下圖是第一層數(shù)據(jù)流圖,虛線部分劃出了系統(tǒng)邊界

銷售管理子系統(tǒng)第一層數(shù)據(jù)流圖

23/92逐一設(shè)計(jì)分E-R圖(續(xù))上圖中把系統(tǒng)功能又分為4個(gè)子系統(tǒng),下面四個(gè)圖是第二層數(shù)據(jù)流圖

圖接收訂單24/92逐一設(shè)計(jì)分E-R圖(續(xù))圖

處理訂單25/92逐一設(shè)計(jì)分E-R圖(續(xù))圖

開發(fā)票

26/92逐一設(shè)計(jì)分E-R圖(續(xù))圖

支付過賬27/92逐一設(shè)計(jì)分E-R圖(續(xù))分E-R圖的框架

28/92逐一設(shè)計(jì)分E-R圖(續(xù))參照第二層數(shù)據(jù)流圖和數(shù)據(jù)字典,遵循兩個(gè)準(zhǔn)則,進(jìn)行如下調(diào)整:(1)訂單與訂單細(xì)節(jié)是1∶n的聯(lián)系(2)原訂單和產(chǎn)品的聯(lián)系實(shí)際上是訂單細(xì)節(jié)和產(chǎn)品的聯(lián)系。(3)圖“發(fā)票主清單”是一個(gè)數(shù)據(jù)存儲(chǔ),不必作為實(shí)體加入分E-R圖(4)工廠對大宗訂貨給予優(yōu)惠29/92逐一設(shè)計(jì)分E-R圖(續(xù))得到分E-R圖如下圖所示

銷售管理子系統(tǒng)的分E-R圖30/92逐一設(shè)計(jì)分E-R圖(續(xù))對每個(gè)實(shí)體定義的屬性如下:顧客:{顧客號,顧客名,地址,電話,信貸狀況,賬目余額}訂單:{訂單號,顧客號,訂貨項(xiàng)數(shù),訂貨日期,交貨日期,工種號,生產(chǎn)地點(diǎn)}訂單細(xì)則:{訂單號,細(xì)則號,零件號,訂貨數(shù),金額}應(yīng)收賬款:{顧客號,訂單號,發(fā)票號,應(yīng)收金額,支付日期,支付金額,當(dāng)前余額,貨款限額}產(chǎn)品描述:{產(chǎn)品號,產(chǎn)品名,單價(jià),重量}折扣規(guī)則:{產(chǎn)品號,訂貨量,折扣}AnIntroductiontoDatabaseSystem31/92視圖的集成各個(gè)局部視圖即分E-R圖建立好后,還需要對它們進(jìn)行合并,集成為一個(gè)整體的數(shù)據(jù)概念結(jié)構(gòu)即總E-R圖。AnIntroductiontoDatabaseSystem32/92視圖集成的兩種方式多個(gè)分E-R圖一次集成一次集成一次集成多個(gè)分E-R圖通常用于局部視圖比較簡單時(shí)逐步累積式首先集成兩個(gè)局部視圖(通常是比較關(guān)鍵的兩個(gè)局部視圖)以后每次將一個(gè)新的局部視圖集成進(jìn)來33/92視圖的集成(續(xù))逐步集成用累加的方式一次集成兩個(gè)分E-R圖34/92視圖的集成(續(xù))集成局部E-R圖的步驟1.合并2.修改與重構(gòu)35/92視圖的集成(續(xù))36/92合并分E-R圖,生成初步E-R圖各分E-R圖存在沖突各個(gè)局部應(yīng)用所面向的問題不同 由不同的設(shè)計(jì)人員進(jìn)行設(shè)計(jì) 各個(gè)分E-R圖之間必定會(huì)存在許多不一致的地方**合并分E-R圖的主要工作與關(guān)鍵所在:合理消除各分E-R圖的沖突37/92合并分E-R圖,生成初步E-R圖(續(xù))

沖突的種類屬性沖突命名沖突結(jié)構(gòu)沖突38/92⒈屬性沖突兩類屬性沖突屬性域沖突:屬性值的類型、取值范圍或取值集合不同。 例1,由于學(xué)號是數(shù)字,因此某些部門(即局部應(yīng)用)將學(xué)號定義為整數(shù)形式,而由于學(xué)號不用參與運(yùn)算,因此另一些部門(即局部應(yīng)用)將學(xué)號定義為字符型形式。 例2,某些部門(即局部應(yīng)用)以出生日期形式表示學(xué)生的年齡,而另一些部門(即局部應(yīng)用)用整數(shù)形式表示學(xué)生的年齡。39/92屬性沖突(續(xù))屬性取值單位沖突。 例:學(xué)生的身高,有的以米為單位,有的以厘米為單位,有的以尺為單位。40/92屬性沖突(續(xù))屬性沖突的解決方法通常用討論、協(xié)商等行政手段加以解決41/92⒉命名沖突兩類命名沖突同名異義:不同意義的對象在不同的局部應(yīng)用中具有相同的名字例,局部應(yīng)用A中將教室稱為房間局部應(yīng)用B中將學(xué)生宿舍稱為房間異名同義(一義多名):同一意義的對象在不同的局部應(yīng)用中具有不同的名字例,有的部門把教科書稱為課本有的部門則把教科書稱為教材42/92命名沖突(續(xù))命名沖突可能發(fā)生在屬性級、實(shí)體級、聯(lián)系級上。其中屬性的命名沖突更為常見。命名沖突的解決方法通過討論、協(xié)商等行政手段加以解決43/92⒊結(jié)構(gòu)沖突三類結(jié)構(gòu)沖突同一對象在不同應(yīng)用中具有不同的抽象例,“課程”在某一局部應(yīng)用中被當(dāng)作實(shí)體在另一局部應(yīng)用中則被當(dāng)作屬性解決方法:通常是把屬性變換為實(shí)體或把實(shí)體變換為屬性,使同一對象具有相同的抽象。變換時(shí)要遵循兩個(gè)準(zhǔn)則。44/92結(jié)構(gòu)沖突(續(xù))同一實(shí)體在不同局部視圖中所包含的屬性不完全相同,或者屬性的排列次序不完全相同。產(chǎn)生原因:不同的局部應(yīng)用關(guān)心的是該實(shí)體的不同側(cè)面。解決方法:使該實(shí)體的屬性取各分E-R圖中屬性的并集,再適當(dāng)設(shè)計(jì)屬性的次序。45/92結(jié)構(gòu)沖突(續(xù))學(xué)生學(xué)號

姓名性別平均成績(a)在局部應(yīng)用A中46/92結(jié)構(gòu)沖突(續(xù))學(xué)生學(xué)號

姓名出生日期年級(b)在局部應(yīng)用B中所在系47/92結(jié)構(gòu)沖突(續(xù))學(xué)生學(xué)號

姓名政治面貌(c)在局部應(yīng)用C中48/92結(jié)構(gòu)沖突(續(xù))學(xué)生

政治面貌

學(xué)號出生日期年級(d)合并后所在系平均成績姓名性別49/92結(jié)構(gòu)沖突(續(xù))實(shí)體之間的聯(lián)系在不同局部視圖中呈現(xiàn)不同的類型 例1,實(shí)體E1與E2在局部應(yīng)用A中是多對多聯(lián)系,而在局部應(yīng)用B中是一對多聯(lián)系 例2,在局部應(yīng)用X中E1與E2發(fā)生聯(lián)系,而在局部應(yīng)用Y中E1、E2、E3三者之間有聯(lián)系。解決方法:根據(jù)應(yīng)用語義對實(shí)體聯(lián)系的類型進(jìn)行綜合或調(diào)整。50/92合并分E-R圖,生成初步E-R圖實(shí)例例:生成學(xué)校管理系統(tǒng)的初步E-R圖

以合并學(xué)籍管理局部視圖,課程管理局部視圖為例這兩個(gè)分E-R圖存在著多方面的沖突:51/92合并分E-R圖,生成初步E-R圖實(shí)例(1)班主任實(shí)際上也屬于教師,也就是說學(xué)籍管理中的班主任實(shí)體與課程管理中的教師實(shí)體在一定程度上屬于異名同義,可以應(yīng)將學(xué)籍管理中的班主任實(shí)體與課程管理中的教師實(shí)體統(tǒng)一稱為教師,統(tǒng)一后教師實(shí)體的屬性構(gòu)成為:教師:{職工號,姓名,性別,職稱,是否為優(yōu)秀班主任}52/92合并分E-R圖,生成初步E-R圖實(shí)例(續(xù))(2)將班主任改為教師后,教師與學(xué)生之間的聯(lián)系在兩個(gè)局部視圖中呈現(xiàn)兩種不同的類型,一種是學(xué)籍管理中教師與學(xué)生之間的指導(dǎo)聯(lián)系,一種是課程管理中教師與學(xué)生之間的教學(xué)聯(lián)系,由于指導(dǎo)聯(lián)系實(shí)際上可以包含在教學(xué)聯(lián)系之中,因此可以將這兩種聯(lián)系綜合為教學(xué)聯(lián)系。53/92合并分E-R圖,生成初步E-R圖實(shí)例(續(xù))(3)性別在兩個(gè)局部應(yīng)用中具有不同的抽象,它在學(xué)籍管理中為實(shí)體,在課程管理中為屬性,按照前面提到的兩個(gè)原則,在合并后的E-R圖中性別只能作為實(shí)體,否則它無法與宿舍實(shí)體發(fā)生聯(lián)系。54/92合并分E-R圖,生成初步E-R圖實(shí)例(續(xù))(4)在兩個(gè)局部E-R圖中,學(xué)生實(shí)體屬性組成及次序都存在差異,應(yīng)將所有屬性綜合,并重新調(diào)整次序。假設(shè)調(diào)整結(jié)果為: 學(xué)生:{學(xué)號,姓名,出生日期,年齡,所在系,年級,平均成績} 解決上述沖突后,學(xué)籍管理分E-R圖與課程管理分E-R圖合并為P198圖6-16的形式。55/92二、修改與重構(gòu)

(消除不必要的冗余,設(shè)計(jì)基本E-R圖)基本任務(wù)消除不必要的冗余,設(shè)計(jì)生成基本E-R圖合并初步E-R圖分E-R圖可能存在冗余的數(shù)據(jù)和冗余的實(shí)體間聯(lián)系基本E-R圖消除不必要的冗余AnIntroductiontoDatabaseSystem56/1419.2邏輯結(jié)構(gòu)設(shè)計(jì)邏輯結(jié)構(gòu)設(shè)計(jì)的任務(wù)概念結(jié)構(gòu)是各種數(shù)據(jù)模型的共同基礎(chǔ)把概念結(jié)構(gòu)設(shè)計(jì)階段設(shè)計(jì)好的基本E-R圖轉(zhuǎn)換為與選用DBMS產(chǎn)品所支持的數(shù)據(jù)模型相符合的邏輯結(jié)構(gòu)AnIntroductiontoDatabaseSystem57/141E-R圖向關(guān)系模型的轉(zhuǎn)換1、轉(zhuǎn)換內(nèi)容2、轉(zhuǎn)換原則AnIntroductiontoDatabaseSystem58/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))E-R圖向關(guān)系模型的轉(zhuǎn)換要解決的問題如何將實(shí)體型和實(shí)體間的聯(lián)系轉(zhuǎn)換為關(guān)系模式如何確定這些關(guān)系模式的屬性和碼轉(zhuǎn)換內(nèi)容將E-R圖轉(zhuǎn)換為關(guān)系模型:將實(shí)體、實(shí)體的屬性和實(shí)體之間的聯(lián)系轉(zhuǎn)換為關(guān)系模式。AnIntroductiontoDatabaseSystem59/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))轉(zhuǎn)換原則⒈一個(gè)實(shí)體型轉(zhuǎn)換為一個(gè)關(guān)系模式。關(guān)系的屬性:實(shí)體型的屬性關(guān)系的碼:實(shí)體型的碼例,學(xué)生實(shí)體可以轉(zhuǎn)換為如下關(guān)系模式:學(xué)生(學(xué)號,姓名,出生日期,所在系,年級,平均成績)性別、宿舍、班級、檔案材料、教師、課程、教室、教科書都分別轉(zhuǎn)換為一個(gè)關(guān)系模式。AnIntroductiontoDatabaseSystem60/141

學(xué)生

學(xué)號出生日期年級所在系平均成績姓名AnIntroductiontoDatabaseSystem61/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))⒉一個(gè)m:n聯(lián)系轉(zhuǎn)換為一個(gè)關(guān)系模式。關(guān)系的屬性:與該聯(lián)系相連的各實(shí)體的碼以及聯(lián)系本身的屬性關(guān)系的碼:各實(shí)體碼的組合

例,“選修”聯(lián)系是一個(gè)m:n聯(lián)系,可以將它轉(zhuǎn)換為如下關(guān)系模式,其中學(xué)號與課程號為關(guān)系的組合碼:選修(學(xué)號,課程號,成績)AnIntroductiontoDatabaseSystem62/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))⒊一個(gè)1:n聯(lián)系可以轉(zhuǎn)換為一個(gè)獨(dú)立的關(guān)系模式,也可以與n端對應(yīng)的關(guān)系模式合并。1)轉(zhuǎn)換為一個(gè)獨(dú)立的關(guān)系模式關(guān)系的屬性:與該聯(lián)系相連的各實(shí)體的碼以及聯(lián)系本身的屬性關(guān)系的碼:n端實(shí)體的碼AnIntroductiontoDatabaseSystem63/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))⒊一個(gè)1:n聯(lián)系可以轉(zhuǎn)換為一個(gè)獨(dú)立的關(guān)系模式,也可以與n端對應(yīng)的關(guān)系模式合并。2)與n端對應(yīng)的關(guān)系模式合并合并后關(guān)系的屬性:在n端關(guān)系中加入1端關(guān)系的碼和聯(lián)系本身的屬性合并后關(guān)系的碼:不變可以減少系統(tǒng)中的關(guān)系個(gè)數(shù),一般情況下更傾向于采用這種方法AnIntroductiontoDatabaseSystem64/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))例,“組成”聯(lián)系為1:n聯(lián)系。 將其轉(zhuǎn)換為關(guān)系模式的兩種方法:

1)使其成為一個(gè)獨(dú)立的關(guān)系模式:組成(學(xué)號,班級號)

2)將其學(xué)生關(guān)系模式合并: 學(xué)生(學(xué)號,姓名,出生日期,所在系,年級,班級號,平均成績)AnIntroductiontoDatabaseSystem65/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))⒋一個(gè)1:1聯(lián)系可以轉(zhuǎn)換為一個(gè)獨(dú)立的關(guān)系模式,也可以與任意一端對應(yīng)的關(guān)系模式合并。1)轉(zhuǎn)換為一個(gè)獨(dú)立的關(guān)系模式關(guān)系的屬性:與該聯(lián)系相連的各實(shí)體的碼以及聯(lián)系本身的屬性關(guān)系的候選碼:每個(gè)實(shí)體的碼均是該關(guān)系的候選碼AnIntroductiontoDatabaseSystem66/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))⒋一個(gè)1:1聯(lián)系可以轉(zhuǎn)換為一個(gè)獨(dú)立的關(guān)系模式,也可以與任意一端對應(yīng)的關(guān)系模式合并。2)與某一端對應(yīng)的關(guān)系模式合并合并后關(guān)系的屬性:加入對應(yīng)關(guān)系的碼和聯(lián)系本身的屬性合并后關(guān)系的碼:不變AnIntroductiontoDatabaseSystem67/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))例,“管理”聯(lián)系為1:1聯(lián)系,可以有三種轉(zhuǎn)換方法:(1)轉(zhuǎn)換為一個(gè)獨(dú)立的關(guān)系模式:

管理(職工號,班級號)或 管理(職工號,班級號)(2)“管理”聯(lián)系與班級關(guān)系模式合并,則只需在班級關(guān)系中加入教師關(guān)系的碼,即職工號: 班級:(班級號,學(xué)生人數(shù),職工號)(3)“管理”聯(lián)系與教師關(guān)系模式合并,則只需在教師關(guān)系中加入班級關(guān)系的碼,即班級號: 教師:(職工號,姓名,性別,職稱,班級號,是否為優(yōu)秀班主任)AnIntroductiontoDatabaseSystem68/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))注意:從理論上講,1:1聯(lián)系可以與任意一端對應(yīng)的關(guān)系模式合并。但在一些情況下,與不同的關(guān)系模式合并效率會(huì)大不一樣。因此究竟應(yīng)該與哪端的關(guān)系模式合并需要依應(yīng)用的具體情況而定。由于連接操作是最費(fèi)時(shí)的操作,所以一般應(yīng)以盡量減少連接操作為目標(biāo)。例如,如果經(jīng)常要查詢某個(gè)班級的班主任姓名,則將管理聯(lián)系與教師關(guān)系合并更好些。AnIntroductiontoDatabaseSystem69/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))⒌三個(gè)或三個(gè)以上實(shí)體間的一個(gè)多元聯(lián)系轉(zhuǎn)換為一個(gè)關(guān)系模式。關(guān)系的屬性:與該多元聯(lián)系相連的各實(shí)體的碼以及聯(lián)系本身的屬性關(guān)系的碼:各實(shí)體碼的組合 例,“講授”聯(lián)系是一個(gè)三元聯(lián)系,可以將它轉(zhuǎn)換為如下關(guān)系模式,其中課程號、職工號和書號為關(guān)系的組合碼:講授(課程號,職工號,書號)AnIntroductiontoDatabaseSystem70/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))⒍同一實(shí)體集的實(shí)體間的聯(lián)系,即自聯(lián)系,也可按上述1:1、1:n和m:n三種情況分別處理。 例,如果教師實(shí)體集內(nèi)部存在領(lǐng)導(dǎo)與被領(lǐng)導(dǎo)的1:n自聯(lián)系,我們可以將該聯(lián)系與教師實(shí)體合并,這時(shí)主碼職工號將多次出現(xiàn),但作用不同,可用不同的屬性名加以區(qū)分:教師:{職工號,姓名,性別,職稱,系主任}AnIntroductiontoDatabaseSystem71/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))⒎具有相同碼的關(guān)系模式可合并。目的:減少系統(tǒng)中的關(guān)系個(gè)數(shù)。合并方法:將其中一個(gè)關(guān)系模式的全部屬性加入到另一個(gè)關(guān)系模式中,然后去掉其中的同義屬性(可能同名也可能不同名),并適當(dāng)調(diào)整屬性的次序。AnIntroductiontoDatabaseSystem72/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))例,“擁有”關(guān)系模式:擁有(學(xué)號,性別)與學(xué)生關(guān)系模式:學(xué)生(學(xué)號,姓名,出生日期,所在系,年級,班級號,平均成績)都以學(xué)號為碼,可以將它們合并為一個(gè)關(guān)系模式:學(xué)生(學(xué)號,姓名,性別,出生日期,所在系,年級,班級號,平均成績)AnIntroductiontoDatabaseSystem73/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))實(shí)例按照上述七條原則,學(xué)生管理子系統(tǒng)中的18個(gè)實(shí)體和聯(lián)系可以轉(zhuǎn)換為下列關(guān)系模型:學(xué)生(學(xué)號,姓名,性別,出生日期,所在系,年級,班級號,平均成績,檔案號) 性別(性別,宿舍樓)宿舍(宿舍編號,地址,性別,人數(shù))班級(班級號,學(xué)生人數(shù)) 教師(職工號,姓名,性別,職稱,班級號,

是否為優(yōu)秀班主任)

AnIntroductiontoDatabaseSystem74/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))

教學(xué)(職工號,學(xué)號)課程(課程號,課程名,學(xué)分,教室號)選修(學(xué)號,課程號,成績)教科書(書號,書名,價(jià)錢)教室(教室編號,地址,容量)講授(課程號,教師號,書號)檔案材料(檔案號,……)AnIntroductiontoDatabaseSystem75/141E-R圖向關(guān)系模型的轉(zhuǎn)換(續(xù))該關(guān)系模型由12個(gè)關(guān)系模式組成。其中:學(xué)生關(guān)系模式包含了“擁有”聯(lián)系、“組成”聯(lián)系、“歸檔”聯(lián)系所對應(yīng)的關(guān)系模式教師關(guān)系模式包含了“管理”聯(lián)系所對應(yīng)的關(guān)系模式;宿舍關(guān)系模式包含了“住宿”聯(lián)系所對應(yīng)的關(guān)系模式;課程關(guān)系模式包含了“開設(shè)”聯(lián)系所對應(yīng)的關(guān)系模式。練習(xí)講解ER和關(guān)系模式的轉(zhuǎn)換構(gòu)建科研院所的科研項(xiàng)目與科研成果管理的E-R圖,并將其轉(zhuǎn)換成相應(yīng)的關(guān)系模式:1、一個(gè)科研項(xiàng)目可以分成多個(gè)成果(鑒定項(xiàng)目)進(jìn)行鑒定,一個(gè)鑒定項(xiàng)目只能來自于一個(gè)科研項(xiàng)目任務(wù);2、一個(gè)鑒定項(xiàng)目最多只對應(yīng)一項(xiàng)獲獎(jiǎng)成果,一項(xiàng)獲獎(jiǎng)成果由鑒定的一個(gè)鑒定項(xiàng)目通過申報(bào)成果而獲得獎(jiǎng)勵(lì);成果申報(bào)時(shí)紀(jì)錄申報(bào)日期和成果批準(zhǔn)情況;3、一個(gè)獲獎(jiǎng)成果對應(yīng)于課題組的多個(gè)獲獎(jiǎng)人,一個(gè)獲獎(jiǎng)人可以有多項(xiàng)科研成果;4、一個(gè)獲獎(jiǎng)成果可以有多個(gè)獲獎(jiǎng)單位,一個(gè)獲獎(jiǎng)單位可以有多想科研成果;AnIntroductiontoDatabaseSystem76/141練習(xí)ER和關(guān)系模式的轉(zhuǎn)換科研項(xiàng)目與科研成果管理E-R圖AnIntroductiontoDatabaseSystem77/141科研項(xiàng)目項(xiàng)目鑒定鑒定項(xiàng)目成果申報(bào)個(gè)人獲獎(jiǎng)獲獎(jiǎng)項(xiàng)目獲獎(jiǎng)人獲獎(jiǎng)單位單位獲獎(jiǎng)成果申報(bào)日期成果批準(zhǔn)情況1N11NNMM練習(xí)ER和關(guān)系模式的轉(zhuǎn)換1、根據(jù)1:N聯(lián)系轉(zhuǎn)換規(guī)則,項(xiàng)目鑒定聯(lián)系及其聯(lián)系的科研項(xiàng)目實(shí)體集和鑒定項(xiàng)目試題集轉(zhuǎn)換成2個(gè)關(guān)系模式:科研項(xiàng)目(項(xiàng)目代號,項(xiàng)目名稱,項(xiàng)目來源,項(xiàng)目類別,立項(xiàng)批文號,承擔(dān)單位,項(xiàng)目負(fù)責(zé)人,經(jīng)費(fèi)額)鑒定項(xiàng)目(鑒定項(xiàng)目代號,項(xiàng)目代號,鑒定項(xiàng)目名稱,項(xiàng)目負(fù)責(zé)人,……)注:當(dāng)鑒定項(xiàng)目代號與項(xiàng)目代號相同時(shí),二者合二為一AnIntroductiontoDatabaseSystem78/141練習(xí)ER和關(guān)系模式的轉(zhuǎn)換2、根據(jù)1:1聯(lián)系的轉(zhuǎn)換規(guī)則,將成果申報(bào)聯(lián)系及其聯(lián)系的鑒定項(xiàng)目實(shí)體集和獲獎(jiǎng)成果實(shí)體集轉(zhuǎn)換成如下兩個(gè)關(guān)系模式:鑒定項(xiàng)目(鑒定項(xiàng)目代號,項(xiàng)目代號,鑒定項(xiàng)目名稱,項(xiàng)目負(fù)責(zé)人,完成時(shí)間,……,成果申報(bào)時(shí)間,成果批準(zhǔn)情況)獲獎(jiǎng)成果(成果編號,成果名稱,獲獎(jiǎng)?lì)悇e,獲獎(jiǎng)級別,……)AnIntroductiontoDatabaseSystem79/141練習(xí)ER和關(guān)系模式的轉(zhuǎn)換3、根據(jù)N:M聯(lián)系的轉(zhuǎn)換規(guī)則,將個(gè)人獲獎(jiǎng)聯(lián)系、獲獎(jiǎng)成果實(shí)體集和獲獎(jiǎng)人實(shí)體集轉(zhuǎn)換成三個(gè)關(guān)系模式:獲獎(jiǎng)人(獲獎(jiǎng)人編號,獲獎(jiǎng)人姓名,排列名次,所屬單位)個(gè)人獲獎(jiǎng)(成果編號,獲獎(jiǎng)人編號)獲獎(jiǎng)成果(成果編號,成果名稱,獲獎(jiǎng)?lì)悇e,獲獎(jiǎng)級別,……)AnIntroductiontoDatabaseSystem80/141練習(xí)ER和關(guān)系模式的轉(zhuǎn)換4、根據(jù)N:M的轉(zhuǎn)換規(guī)則,單位獲獎(jiǎng)聯(lián)系及獲獎(jiǎng)成果實(shí)體集和獲獎(jiǎng)單位實(shí)體集轉(zhuǎn)換成三個(gè)關(guān)系模式:獲獎(jiǎng)單位(獲獎(jiǎng)單位編號,獲獎(jiǎng)單位名稱,……)單位獲獎(jiǎng)(成果編號,獲獎(jiǎng)單位編號)獲獎(jiǎng)成果(成果編號,成果名稱,……)5、合并上述關(guān)系模式6、根據(jù)經(jīng)驗(yàn)簡化,比如將個(gè)人獲獎(jiǎng)關(guān)系模式中的成果編號直接放到獲獎(jiǎng)人關(guān)系模式中,并去掉個(gè)人關(guān)系模式等;AnIntroductiontoDatabaseSystem81/1412022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院82

實(shí)現(xiàn)示例2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院83A、VB訪問SQLServer使用VisualBasic作為前端開發(fā)語言,與SQLServer接口有三種常用的方法,即:

*數(shù)據(jù)訪問對象/Jet

*為ODBCAPI編程

*使用SQLServer的VisualBasic庫(VBSQL)為DB庫API編程2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院841數(shù)據(jù)訪問對象/JetVisualBasic支持DataAccessObjects(DAOs)的子集DAO的方法雖然不是性能最好的管理客戶機(jī)—服務(wù)器之間的對話方式,但它確有許多優(yōu)點(diǎn)。使用DAOs訪問SQLServer的過程如下:應(yīng)用程序準(zhǔn)備好語句并送至Jet,Jet引擎(MASJT200.DLL)優(yōu)化查詢,載入驅(qū)動(dòng)程序管理器并與之通訊,驅(qū)動(dòng)程序管理器(ODBC.DLL)通地調(diào)用驅(qū)動(dòng)器(SQLSRVR.DLL)的函數(shù),實(shí)現(xiàn)連接到數(shù)據(jù)源,翻譯并向SQLServer提交SQL語句且返回結(jié)果。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院85DAOs訪問SQLServer的VB實(shí)例''''FormDeclarations

DimmydbAsDatabase

DimmydynasetAsDynaset

PrivateSubForm_Load()

Setmydb=OpenDatabase("",Fa|se,Fa|se,"ODBC;DSN=Myserver;WSID=LCL;DATABASE=sa|es")

Setmydynaset=mydbCreateDynaset("Select*fromCustomers")

EndSub

2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院86述例子是以非獨(dú)占、非只讀方式打開sales數(shù)據(jù)庫,并檢索Customers表中的所有字段。OpenDatabase函數(shù)的最后一個(gè)參數(shù)是ODBC連接字符串參數(shù),它指明了MicrosoftAccess連接到SQLServer所需要知道的一些內(nèi)容。其中“DSN”為數(shù)據(jù)源名,“WSID”為工作站名,“DATABASE”為所要訪問的數(shù)據(jù)庫名。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院872用ODBCAPI編程ODBC(OpenDatabaseConnectivity)的思想是訪問異種數(shù)據(jù)庫的一種可移植的方式。與數(shù)據(jù)資源對話的公用函數(shù)組裝在一個(gè)稱為驅(qū)動(dòng)程序管理器(ODBC.DLL)的動(dòng)態(tài)連接中。應(yīng)用程序調(diào)用驅(qū)動(dòng)程序管理器中的函數(shù),而驅(qū)動(dòng)程序管理器反過來通過驅(qū)動(dòng)器反過來通來驅(qū)動(dòng)器(SQLSRVR.DLL)把它們送到服務(wù)器中。

2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院88ODBCAPI編程的常用函數(shù)SQLALLocEnv初始化ODBC環(huán)境,返回環(huán)境句柄

SQLALLocConnect為連接句柄分配內(nèi)存并返回連接句柄

SQLConnect連接一個(gè)SQL數(shù)據(jù)資源

SQLDriverConnect連接一個(gè)SQL數(shù)據(jù)資源,允許驅(qū)動(dòng)器向用戶詢問信息

SQLALLocStmt為語句句柄分配內(nèi)存并返回語句句柄

SQLExecDirect把SQL語句送到服務(wù)器

SQLFetchAdvances到結(jié)果集的下一行(或第一行)

SQLGetData從結(jié)果集的特定的一列取回?cái)?shù)據(jù)

SQLFreeStmt釋放與語句句柄相關(guān)的資源

SQLDisconnect切斷連接

SQLFreeConnect釋放與連接句柄相關(guān)的資源

SQLFreeEnv釋放與環(huán)境句柄相關(guān)的資源2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院89代碼GlobalgiHEnvAsLong

GlobalgiHDBAsLong

GlobalgiHStmtAsLong

DimmyResultAsinteger

DimmyConnectionAsSrting

DimmyBuffAsString*256

DimmyBufflenAsInteger

IfSQLA||ocEnv(giHEnv)<>SQL_SUCCESSThen

MsgBox"A||ocationcouldn''''thappen!"

Endif

ifSQL||ocConnect(giHEnv,giHDB)<>SQL_SUCCESSThen

MsgBox"SQLServercouldn''''tconnect!"

Endif

myConnection="DSN=myServer;UID=|c|;PWD=;APP=ODBCTest;WS|D=LCL;DATABASE=sales"

myResult=SQLDriverConnect(giHDB,Test,form1.hWnd,myConnection.len(myConnection),

myBuff,256,myBufflen,SQL_DRIVER_COMPLETE_REQUIED)

myResult=SQLA||ocStmt(giHDS,giHStmt)

myResult=SQLFreeStmt(giHStmt,SQL_COLSE)

rsSQL="Select*fromCustomersWhereCity="Wuhan""

myResult=SQLExecDirect(giHStmt,rsSQL,Len(rsSQL))2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院903使用VBSQL對DB庫API編程DB庫是SQLServer的本地API,SQLServer的VisualBasic庫(VBSQL)為VisualBasic程序員提供API。從一定意義上說,VBSQL是連接VisualBasic程序到SQLServer的性能最好最直接的方式。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院91VBSQL包含以下三個(gè)文件VBSQL.VBX包含庫函數(shù),具有訪問重要的消息和處理錯(cuò)誤的能力

VBSQL.BI包括所有的常量和變量說明

VBSQL.HLPWindows幫助文件,使用VBSQL的指南

使用VBSQL時(shí),必需將VBSQL.BI加入到VisualBasic工程文件中,并確保VB程序運(yùn)行時(shí)有

VBSQL.VBX文件。

2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院92函數(shù)Sqllnit在客戶機(jī)上裝載DB庫

SqlOpenConnection打開服務(wù)器連接,返回連接句柄

SqlCmd在客戶機(jī)上建立批處理命令

SqlExec向服務(wù)器提交批處理命令

Sqlrexu|ts把客戶機(jī)定位在第一條(或下一條)結(jié)果集的開端

SqlNextRow驅(qū)動(dòng)每個(gè)結(jié)果集的行之間的循環(huán)

SqlData訪問一個(gè)特定列的數(shù)據(jù)

SqlC|ose切斷特定的連接

SqlExit切斷所有找開的連接

SqlWinExit卸下DB庫一般的DB庫API編程的過程是這樣的:先通過調(diào)用SqlInit對DB庫進(jìn)行初始化,再調(diào)用SqlConnection打開一個(gè)連接,然后就可做一些工作。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院93初始化DB庫并登錄到服務(wù)器的通用例程PrivateSub|nitia|izeApp|ication()

DBL|B-VERS|ON=Sq||nit()

|fDBL|B_VERS|ON=""Then

MsgBox"Couldnotinitia|izeDBL|B!Exitapp|ication.",MB_|CONEXCLAMAT|ON

End

Endif

EndSub

PrivateFunctionLoginToServer()Asinteger

loginToServer=SUCCEED

Status%=Sq|SetloginTime%(loginTimeOut)

|fgiSq|Conn<>0Then

Sq|C|ose(giSq|Conn)''''關(guān)閉已打開的連接

giSq|Conn=Sq|OpenConnection(gsServerName,gsLogin|D,gsPassword,ProgramName,ProgramName)

|fgiSq|Conn<>oThen

|iresu|t=Sq|Use(giSq|Conn,"Sales")

Else

LogintoServer=FA|L

End|f

EndFunction2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院94性能比較以上三種訪問SQLServer的方法各有各的特點(diǎn)。DAOs方法是基于對象的,因而便于使用,但是它從VisualBasic到SQLServer的最慢的方式。ODBCAPI和VBSQL方法從本質(zhì)上講是基于程序的。ODBCAPI方法通用性好,允許最強(qiáng)的互操作性,編程簡單,但速度慢于VBSQL方法。VBSQL方法通過VBSQL控件,提供了重要的SQL`Server前端應(yīng)用程序所需的靈活性、強(qiáng)大功能和良好性能。它具有真正的事件驅(qū)動(dòng)及錯(cuò)誤處理能力,完全支持異步處理、游標(biāo)和計(jì)算列等。這些都是VBSQL方法超出其它方法的優(yōu)勢,但其編程稍復(fù)雜。至于實(shí)際使用哪一種接口方式,在很大程度上依賴于用戶的應(yīng)用程序的具體情況而定。

2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院95B、JDBC連接SQLServer2000一、下載SQLSERVER2000的jdbc驅(qū)動(dòng)程序并安裝。/downloads/default.asp?URL=/downloads/sample.asp?url=/msdn-files/027/001/779/msdncompositedoc.xml&FinishURL=%2Fdownloads%2Frelease%2Easp%3FReleaseID%3D38312%26area%3Dsearch%26ordinal%3D1%26redirect%3Dno2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院96二、啟動(dòng)JBuilder6.0。打開Tools-->EnterpriseSetup-->DataBaseDrivers-->Add-->New,然后命名"MicrosoftSqlServerJDBCDriver",選擇sqlserver2000--jdbc驅(qū)動(dòng)的安裝路徑,加入三個(gè)jar文件(在安裝目錄的lib下面)。確定。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院97三、新建project,然后在project的屬性中,選擇Paths-->RequiredLibraries,添加“MicrosoftSqlServerJDBCDriver”。四、在程序上面添加:

importcom.microsoft.*;

//加載類庫2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院98代碼voidjButton1_actionPerformed(ActionEvente){

try{

Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");

Connectionconn=DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433;User=sa;Password=;DatabaseName=maxwell");

Statementstmt=conn.createStatement();

Stringsql="select*fromemployee";

ResultSetrs=stmt.executeQuery(sql);

while(rs.next())

{

JOptionPane.showMessageDialog(null,rs.getString("name"),"員工名稱",JOptionPane.YES_OPTION+JOptionPane.INFORMATION_MESSAGE);

}

}

catch(Exceptionex)

{

System.err.println(ex.getMessage());

}

}2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院99C、VisualC++ADOADO是目前在Windows環(huán)境中比較流行的客戶端數(shù)據(jù)庫編程技術(shù)。ADO是建立在OLEDB底層技術(shù)之上的高級編程接口,因而它兼具有強(qiáng)大的數(shù)據(jù)處理功能(處理各種不同類型的數(shù)據(jù)源、分布式的數(shù)據(jù)處理等等)和極其簡單、易用的編程接口,因而得到了廣泛的應(yīng)用。而且按微軟公司的意圖,OLEDB和ADO將逐步取代ODBC和DAO。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院100一、在VC++中使用ADO編程ADO實(shí)際上就是由一組Automation對象構(gòu)成的組件,因此可以象使用其它任何Automation對象一樣使用ADO。ADO中最重要的對象有三個(gè):Connection、Command和Recordset,它們分別表示連接對象、命令對象和記錄集對象。。如果熟悉使用MFC中的ODBC類(CDatabase、CRecordset)編程,那么學(xué)習(xí)ADO編程十分容易。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院1011、使用預(yù)處理指令#import但要注意不能放在stdAfx.h文件的開頭,而應(yīng)該放在所有include指令的后面。否則在編譯時(shí)會(huì)出錯(cuò)。

程序在編譯過程中,VC++會(huì)讀出msado15.dll中的類型庫信息,自動(dòng)產(chǎn)生兩個(gè)該類型庫的頭文件和實(shí)現(xiàn)文件msado15.tlh和msado15.tli(在您的Debug或Release目錄下)。在這兩個(gè)文件里定義了ADO的所有對象和方法,以及一些枚舉型的常量等。我們的程序只要直接調(diào)用這些方法就行了,與使用MFC中的COleDispatchDriver類調(diào)用Automation對象十分類似。使用ADO編程時(shí)可以采用以下三種方法之一:#import"C:\ProgramFiles\CommonFiles\System\ADO\msado15.dll"\

no_namespacerename("EOF","EndOfFile")2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院1022、使用MFC中的CIDispatchDriver通過讀取msado15.dll中的類型庫信息,建立一個(gè)COleDispatchDriver類的派生類,然后通過它調(diào)用ADO對象。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院1033、直接用COM提供的API以上三種方法,第一和第二種類似,可能第一種好用一些,第三種編程可能最麻煩。但可能第三種方法也是效率最高的,程序的尺寸也最小,并且對ADO的控制能力也最強(qiáng)。第一種方法不支持方法調(diào)用中的默認(rèn)參數(shù),當(dāng)然第二種方法也是這樣,但第三種就不是這樣了。采用第三種方法的水平也最高。當(dāng)你需要繞過ADO而直接調(diào)用OLEDB底層的方法時(shí),就一定要使用第三種方法了。ADO編程的關(guān)鍵,就是熟練地運(yùn)用ADO提供的各種對象(object)、方法(method)、屬性(property)和容器(collection)。另外,如果是在MSSQL或Oracle等大型數(shù)據(jù)庫上編程,還要能熟練使用SQL語言。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院104二、使用#import方法的編程步驟1、添加#import指令打開stdafx.h文件,將下列內(nèi)容添加到所有的include指令之后:#include<icrsint.h>//IncludesupportforVC++Extensions

#import"C:\ProgramFiles\CommonFiles\System\ADO\msado15.dll"\

no_namespacerename("EOF","adoEOF")其中icrsint.h文件包含了VC++擴(kuò)展的一些預(yù)處理指令、宏等的定義,用于COM編程時(shí)使用。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院1052、定義_ConnectionPtr型變量,并建立數(shù)據(jù)庫連接建立了與數(shù)據(jù)庫服務(wù)器的連接后,才能進(jìn)行其他有關(guān)數(shù)據(jù)庫的訪問和操作。ADO使用Connection對象來建立與數(shù)據(jù)庫服務(wù)器的連接,所以它相當(dāng)于MFC中的CDatabase類。和CDatabase類一樣,調(diào)用Connection對象的Open方法即可建立與服務(wù)器的連接。數(shù)據(jù)類型_ConnectionPtr實(shí)際上就是由類模板_com_ptr_t而得到的一個(gè)具體的實(shí)例類,其定義可以到msado15.tlh、comdef.h和comip.h這三個(gè)文件中找到。在msado15.tlh中有:_COM_SMARTPTR_TYPEDEF(_Collection,__uuidof(_Collection));

經(jīng)宏擴(kuò)展后就得到了_ConnectionPtr類。_ConnectionPtr類封裝了Connection對象的Idispatch接口指針,及一些必要的操作。我們就是通過這個(gè)指針來操縱Connection對象。類似地,后面用到的_CommandPtr和_RecordsetPtr類型也是這樣得到的,它們分別表示命令對象指針和記錄集對象的指針。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院106(1)、連接到MSSQLServer

注意連接字符串的格式,提供正確的連接字符串是成功連接到數(shù)據(jù)庫服務(wù)器的第一步,有關(guān)連接字符串的詳細(xì)信息參見微軟MSDNLibrary光盤。

本例連接字符串中的server_name,database_name,user_name和password在編程時(shí)都應(yīng)該替換成實(shí)際的內(nèi)容。_ConnectionPtrpMyConnect=NULL;

HRESULThr=pMyConnect.CreateInstance(__uuidof(Connection)));

if(FAILED(hr))return;

_bstr_tstrConnect="Provider=SQLOLEDB;Server=server_name;"

"Database=database_name;uid=user_name;pwd=password;";

//connectingtothedatabaseservernow:

try{pMyConnect->Open(strConnect,"","",NULL);}

catch(_com_error&e)

{

::MessageBox(NULL,e.Description(),"警告",MB_OK│MB_ICONWARNING);

}

注意Connection對象的Open方法中的連接字符串參數(shù)必須是BSTR或_bstr_t類型。另外,本例是直接通過OLEDBProvider建立連接,所以無需建立數(shù)據(jù)源。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院1072)、通過ODBCDriver連接到DatabaseServer連接字符串格式與直接用ODBC編程時(shí)的差不多:_bstr_tstrConnect="DSN=datasource_name;Database=database_name;uid=user_name;pwd=password;";

此時(shí)與ODBC編程一樣,必須先建立數(shù)據(jù)源。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院1083、定義_RecordsetPtr型變量,并打開數(shù)據(jù)集

定義_RecordsetPtr型變量,然后通過它調(diào)用Recordset對象的Open方法,即可打開一個(gè)數(shù)據(jù)集。所以Recordset對象與MFC中的CRecordset類類似,它也有當(dāng)前記錄、當(dāng)前記錄指針的概念。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院109_RecordsetPtrm_pRecordset;

if(!FAILED(m_pRecordset.CreateInstance(__uuidof(Recordset)))

{

m_pDoc->m_initialized=FALSE;

return;

}

try{

m_pRecordset->Open(_variant_t("mytable"),

_variant_t((IDispatch*)pMyConnect,true),adOpenKeyset,

adLockOptimistic,adCmdTable);

}

catch(_com_error&e)

{

::MessageBox(NULL,"無法打開mytable表。","提示",

MB_OK│MB_ICONWARNING);

}

Recordset對象的Open方法非常重要,它的第一個(gè)參數(shù)可以是一個(gè)SQL語句、一個(gè)表的名字或一個(gè)命令對象等等;第二個(gè)參數(shù)就是前面建立的連接對象的指針。此外,用Connection和Command對象的Execute方法也能得到記錄集,但是只讀的。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院1104、讀取當(dāng)前記錄的數(shù)據(jù)try{

m_pRecordset->MoveFirst();

while(m_pRecordset->adoEOF==VARIANT_FALSE)

{

//Retrievecolumn'svalue:

CStringsName=(char*)(_bstr_t)(m_pRecordset->Fields->GetItem

(_variant_t("name"))->Value);

shortcAge=(short)(m_pRecordset->Fields->GetItem

(_variant_t("age"))->Value);

//Dosomethingwhatyouwanttodo:

......

m_pRecordset->MoveNext();

}

}//try

catch(_com_error&e)

{

CStringstr=(char*)e.Description();

::MessageBox(NULL,str+"\n又出毛病了。","提示",

MB_OK│MB_ICONWARNING);

}

本例中的name和age都是字段名,讀取的字段值分別保存在sName和cAge變量內(nèi)。例中的Fields是Recordset對象的容器,GetItem方法返回的是Field對象,而Value則是Field對象的一個(gè)屬性(即該字段的值)。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院111要獲得Field對象的Value屬性的值可以直接用屬性名Value來引用它(如上例),但也可以調(diào)用Get方法,例如:CStringsName=(char*)(_bstr_t)(m_pRecordset->Fields->GetItem

(_variant_t("name"))->GetValue());

從此例還可以看到,判斷是否到達(dá)記錄集的末尾,使用記錄集的adoEOF屬性,其值若為真即到了結(jié)尾,反之則未到。判斷是否到達(dá)記錄集開頭,則可用BOF屬性。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院1125、修改數(shù)據(jù)方法一:try{

m_pRecordset->MoveFirst();

while(m_pRecordset->adoEOF==VARIANT_FALSE)

{

m_pRecordset->Fields->GetItem

(_variant_t("姓名"))->Value=_bstr_t("趙薇");

......

m_pRecordset->Update();

m_pRecordset->MoveNext();

}

}//try

改變了Value屬性的值,即改變了字段的值。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院113方法二:m_pRecordset->Fields->GetItem

(_variant_t(“姓名”))->PutValue(_bstr_t(“張三"));方法三:就是用定義綁定類的方法2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院1146、添加記錄新記錄添加成功后,即自動(dòng)成為當(dāng)前記錄。AddNew方法有兩種形式,一個(gè)含有參數(shù),而另一個(gè)則不帶參數(shù)。

方法一(不帶參數(shù))://Addnewrecordintothistable:

try{

if(!m_pRecordset->Supports(adAddNew))return;

m_pRecordset->AddNew();

m_pRecordset->Fields->GetItem

(_variant_t("姓名"))->Value=_bstr_t("趙薇");

m_pRecordset->Fields->GetItem

(_variant_t("性別"))->Value=_bstr_t("女");

m_pRecordset->Fields->GetItem

(_variant_t("age"))->Value=_variant_t((short)20);

m_pRecordset->Fields->GetItem

(_variant_t("marry"))->Value=_bstr_t("未婚");

m_pRecordset->Update();

}//try

catch(_com_error&e)

{

::MessageBox(NULL,"又出毛病了。","提示",MB_OK│MB_ICONWARNING);

}

這種方法弄完了還要調(diào)用Update()。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院115方法二(帶參數(shù)):_variant_tvarName[4],narValue[4];

varName[0]=L“姓名”;

varName[1]=L“性別”;

varName[2]=L“age”;

varName[3]=L“marry”;

narValue[0]=_bstr_t(“張三");

narValue[1]=_bstr_t("女");

narValue[2]=_variant_t((short)20);

narValue[3]=_bstr_t("未婚");

constintnCrit=sizeofvarName/sizeofvarName[0];

//CreateSafeArrayBoundsandinitializethearray

SAFEARRAYBOUNDrgsaName[1],rgsaValue[1];

rgsaName[0].lLbound=0;

rgsaName[0].cElements=nCrit;

SAFEARRAY*psaName=SafeArrayCreate(VT_VARIANT,1,rgsaName);

rgsaValue[0].lLbound=0;

rgsaValue[0].cElements=nCrit;

SAFEARRAY*psaValue=SafeArrayCreate(VT_VARIANT,1,rgsaValue);

//Setthevaluesforeachelementofthearray

HRESULThr1=S_OK.hr2=S_OK;

for(longi=0;i<nCrit&&SUCCEEDED(hr1)&&SUCCEEDED(hr2);i++)

{

hr1=SafeArrayPutElement(psaName,&i,&varName[i]);

hr2=SafeArrayPutElement(psaValue,&i,&narValue[i]);}

//InitializeandfilltheSafeArray

VARIANTvsaName,vsaValue;

vsaName.vt=VT_VARIANT│VT_ARRAY;

vsaValue.vt=VT_VARIANT│VT_ARRAY;

V_ARRAY(&vsaName)=psaName;//&vsaName->parray=psaName;

//seedefinitioninoleauto.hfile.

V_ARRAY(&vsaValue)=psaValue;

//Addanewrecord:

m_pRecordset->AddNew(vsaName,vsaValue);

這種方法不需要調(diào)用Update,因?yàn)樘砑雍?,ADO會(huì)自動(dòng)調(diào)用它。

2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院1167、刪除記錄

調(diào)用Recordset的Delete方法就行了,刪除的是當(dāng)前記錄。要了解Delete的其它用法請查閱參考文獻(xiàn)。try{

m_pRecordset->MoveFirst();

while(m_pRecordset->adoEOF==VARIANT_FALSE)

{

CStringsName=(char*)(_bstr_t)(m_pRecordset->Fields->GetItem

(_variant_t("姓名"))->Value);

if(::MessageBox(NULL,"姓名="+sName+"\n刪除她嗎?",

"提示",MB_YESNO│MB_ICONWARNING)==IDYES)

{

m_pRecordset->Delete(adAffectCurrent);

m_pRecordset->Update();

}

m_pRecordset->MoveNext();

}

}//try

catch(_com_error&e)

{

::MessageBox(NULL,"又出毛病了。","提示",MB_OK│MB_ICONWARNING);

}2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院1178、使用帶參數(shù)的命令

Command對象所代表的就是一個(gè)Provider能夠理解的命令,如SQL語句等。使用Command對象的關(guān)鍵就是把表示命令的語句設(shè)置到CommandText屬性中,然后調(diào)用Command對象的Execute方法就行了。一般情況下在命令中無需使用參數(shù),但有時(shí)使用參數(shù),可以增加其靈活性和效率。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院118(1).建立連接、命令對象和記錄集對象

本例中表示命令的語句就是一個(gè)SQL語句(SELECT語句)。SELECT語句中的問號?就代表參數(shù),如果要多個(gè)參數(shù),就多放幾個(gè)問號,每個(gè)問號代表一個(gè)參數(shù)。_ConnectionPtrConn1;

_CommandPtrCmd1;

ParametersPtr*Params1=NULL;//Notaninstanceofasmartpointer.

_ParameterPtrParam1;

_RecordsetPtrRs1;

try

{

//CreateConnectionObject(1.5Version)

Conn1.CreateInstance(__uuidof(Connection));

Conn1->ConnectionString=bstrConnect;

Conn1->Open(bstrEmpty,bstrEmpty,bstrEmpty,-1);

//CreateCommandObject

Cmd1.CreateInstance(__uuidof(Command));

Cmd1->ActiveConnection=Conn1;

Cmd1->CommandText=_bstr_t("SELECT*FROMmytableWHEREage<?");

}//try

要注意命令對象必須與連接對象關(guān)聯(lián)起來才能起作用,本例中將命令對象的ActiveConnection屬性設(shè)置為連接對象的指針,即為此目的:Cmd1->ActiveConnection=Conn1;2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院119(2).創(chuàng)建參數(shù)對象,并給參數(shù)賦值//CreateParameterObject

Param1=Cmd1->CreateParameter(_bstr_t(bstrEmpty),

adInteger,

adParamInput,

-1,

_variant_t((long)5));

Param1->Value=_variant_t((long)5);

Cmd1->Parameters->Append(Param1);

用命令對象的方法來創(chuàng)建一個(gè)參數(shù)對象,其中的長度參數(shù)(第三個(gè))如果是固定長度的類型,就填-1,如果是字符串等可變長度的就填其實(shí)際長度。Parameters是命令對象的一個(gè)容器,它的Append方法就是把創(chuàng)建的參數(shù)對象追加到該容器里。Append進(jìn)去的參數(shù)按先后順序與SQL語句中的問號從左至右一一對應(yīng)。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院120(3).執(zhí)行命令打開記錄集//OpenRecordsetObject

Rs1=Cmd1->Execute(&vtEmpty,&vtEmpty2,adCmdText);

但要注意,用Command和Connection對象的Execute方法得到的Recordset是只讀的。因?yàn)樵诖蜷_Recordset之前,我們無法設(shè)置它的LockType屬性(其默認(rèn)值為只讀)。而在打開之后設(shè)置LockType不起作用。2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院121要想能修改數(shù)據(jù),還是要用Recordset自己的Open方法才行,如:try{

m_pRecordset->Open((IDispatch*)Cmd1,vtMissing,

adOpenStatic,adLockOptimistic,adCmdUnspecified);

}

catch(_com_error&e)

{

::MessageBox(NULL,"mytable表不存在。","提示",MB_OK│MB_ICONWARNING);

}2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院1229、響應(yīng)ADO的通知事件

通知事件就是當(dāng)某個(gè)特定事件發(fā)生時(shí),由Provider通知客戶程序,換句話說,就是由Provider調(diào)用客戶程序中的一個(gè)特定的方法(即事件的處理函數(shù))。所以為了響應(yīng)一個(gè)事件,最關(guān)鍵的就是要實(shí)現(xiàn)事件的處理函數(shù)。

2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院123(1).從ConnectionEventsVt接口派生出一個(gè)類

為了響應(yīng)_Connection的通知事件,應(yīng)該從ConnectionEventsVt接口派生出一個(gè)類:classCConnEvent:publicConnectionEventsVt

{

private:

ULONGm_cRef;

public:

CConnEvent(){m_cRef=0;};

~CConnEvent(){};

STDMETHODIMPQueryInterface(REFIIDriid,void**ppv);

STDMETHODIMP_(ULONG)AddRef(void);

STDMETHODIMP_(ULONG)Release(void);

STDMETHODIMPraw_InfoMessage(

structError*pError,

EventStatusEnum*adStatus,

struct_Connection*pConnection);

STDMETHODIMPraw_BeginTransComplete(

LONGTransactionLevel,

structError*pError,

EventStatusEnum*adStatus,

struct_Connection*pConnection);

......

};2022/11/3廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院124(2).實(shí)現(xiàn)每一個(gè)事件的處理函數(shù)(凡是帶raw_前綴的方法都把它實(shí)現(xiàn)了):STDMETHODIMPCConnEvent::raw_InfoMessage(

structError*pError,

EventStatusEnum*adStatus,

struct_Connection*pCon

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(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ǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論