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

下載本文檔

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

文檔簡介

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

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

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

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

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

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

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

開發(fā)票

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

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

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

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

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

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

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

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

政治面貌

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

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

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

學生

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

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

1)使其成為一個獨立的關系模式:組成(學號,班級號)

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

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

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

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

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

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

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

*為ODBCAPI編程

*使用SQLServer的VisualBasic庫(VBSQL)為DB庫API編程2022/11/3廣東工業(yè)大學計算機學院841數(shù)據(jù)訪問對象/JetVisualBasic支持DataAccessObjects(DAOs)的子集DAO的方法雖然不是性能最好的管理客戶機—服務器之間的對話方式,但它確有許多優(yōu)點。使用DAOs訪問SQLServer的過程如下:應用程序準備好語句并送至Jet,Jet引擎(MASJT200.DLL)優(yōu)化查詢,載入驅(qū)動程序管理器并與之通訊,驅(qū)動程序管理器(ODBC.DLL)通地調(diào)用驅(qū)動器(SQLSRVR.DLL)的函數(shù),實現(xiàn)連接到數(shù)據(jù)源,翻譯并向SQLServer提交SQL語句且返回結(jié)果。2022/11/3廣東工業(yè)大學計算機學院85DAOs訪問SQLServer的VB實例''''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è)大學計算機學院86述例子是以非獨占、非只讀方式打開sales數(shù)據(jù)庫,并檢索Customers表中的所有字段。OpenDatabase函數(shù)的最后一個參數(shù)是ODBC連接字符串參數(shù),它指明了MicrosoftAccess連接到SQLServer所需要知道的一些內(nèi)容。其中“DSN”為數(shù)據(jù)源名,“WSID”為工作站名,“DATABASE”為所要訪問的數(shù)據(jù)庫名。2022/11/3廣東工業(yè)大學計算機學院872用ODBCAPI編程ODBC(OpenDatabaseConnectivity)的思想是訪問異種數(shù)據(jù)庫的一種可移植的方式。與數(shù)據(jù)資源對話的公用函數(shù)組裝在一個稱為驅(qū)動程序管理器(ODBC.DLL)的動態(tài)連接中。應用程序調(diào)用驅(qū)動程序管理器中的函數(shù),而驅(qū)動程序管理器反過來通過驅(qū)動器反過來通來驅(qū)動器(SQLSRVR.DLL)把它們送到服務器中。

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

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

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

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

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

SQLExecDirect把SQL語句送到服務器

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

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

SQLFreeStmt釋放與語句句柄相關的資源

SQLDisconnect切斷連接

SQLFreeConnect釋放與連接句柄相關的資源

SQLFreeEnv釋放與環(huán)境句柄相關的資源2022/11/3廣東工業(yè)大學計算機學院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è)大學計算機學院903使用VBSQL對DB庫API編程DB庫是SQLServer的本地API,SQLServer的VisualBasic庫(VBSQL)為VisualBasic程序員提供API。從一定意義上說,VBSQL是連接VisualBasic程序到SQLServer的性能最好最直接的方式。2022/11/3廣東工業(yè)大學計算機學院91VBSQL包含以下三個文件VBSQL.VBX包含庫函數(shù),具有訪問重要的消息和處理錯誤的能力

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

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

使用VBSQL時,必需將VBSQL.BI加入到VisualBasic工程文件中,并確保VB程序運行時有

VBSQL.VBX文件。

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

SqlOpenConnection打開服務器連接,返回連接句柄

SqlCmd在客戶機上建立批處理命令

SqlExec向服務器提交批處理命令

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

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

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

SqlC|ose切斷特定的連接

SqlExit切斷所有找開的連接

SqlWinExit卸下DB庫一般的DB庫API編程的過程是這樣的:先通過調(diào)用SqlInit對DB庫進行初始化,再調(diào)用SqlConnection打開一個連接,然后就可做一些工作。2022/11/3廣東工業(yè)大學計算機學院93初始化DB庫并登錄到服務器的通用例程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)''''關閉已打開的連接

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

2022/11/3廣東工業(yè)大學計算機學院95B、JDBC連接SQLServer2000一、下載SQLSERVER2000的jdbc驅(qū)動程序并安裝。/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è)大學計算機學院96二、啟動JBuilder6.0。打開Tools-->EnterpriseSetup-->DataBaseDrivers-->Add-->New,然后命名"MicrosoftSqlServerJDBCDriver",選擇sqlserver2000--jdbc驅(qū)動的安裝路徑,加入三個jar文件(在安裝目錄的lib下面)。確定。2022/11/3廣東工業(yè)大學計算機學院97三、新建project,然后在project的屬性中,選擇Paths-->RequiredLibraries,添加“MicrosoftSqlServerJDBCDriver”。四、在程序上面添加:

importcom.microsoft.*;

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

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

no_namespacerename("EOF","EndOfFile")2022/11/3廣東工業(yè)大學計算機學院1022、使用MFC中的CIDispatchDriver通過讀取msado15.dll中的類型庫信息,建立一個COleDispatchDriver類的派生類,然后通過它調(diào)用ADO對象。2022/11/3廣東工業(yè)大學計算機學院1033、直接用COM提供的API以上三種方法,第一和第二種類似,可能第一種好用一些,第三種編程可能最麻煩。但可能第三種方法也是效率最高的,程序的尺寸也最小,并且對ADO的控制能力也最強。第一種方法不支持方法調(diào)用中的默認參數(shù),當然第二種方法也是這樣,但第三種就不是這樣了。采用第三種方法的水平也最高。當你需要繞過ADO而直接調(diào)用OLEDB底層的方法時,就一定要使用第三種方法了。ADO編程的關鍵,就是熟練地運用ADO提供的各種對象(object)、方法(method)、屬性(property)和容器(collection)。另外,如果是在MSSQL或Oracle等大型數(shù)據(jù)庫上編程,還要能熟練使用SQL語言。2022/11/3廣東工業(yè)大學計算機學院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++擴展的一些預處理指令、宏等的定義,用于COM編程時使用。2022/11/3廣東工業(yè)大學計算機學院1052、定義_ConnectionPtr型變量,并建立數(shù)據(jù)庫連接建立了與數(shù)據(jù)庫服務器的連接后,才能進行其他有關數(shù)據(jù)庫的訪問和操作。ADO使用Connection對象來建立與數(shù)據(jù)庫服務器的連接,所以它相當于MFC中的CDatabase類。和CDatabase類一樣,調(diào)用Connection對象的Open方法即可建立與服務器的連接。數(shù)據(jù)類型_ConnectionPtr實際上就是由類模板_com_ptr_t而得到的一個具體的實例類,其定義可以到msado15.tlh、comdef.h和comip.h這三個文件中找到。在msado15.tlh中有:_COM_SMARTPTR_TYPEDEF(_Collection,__uuidof(_Collection));

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

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

本例連接字符串中的server_name,database_name,user_name和password在編程時都應該替換成實際的內(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è)大學計算機學院1072)、通過ODBCDriver連接到DatabaseServer連接字符串格式與直接用ODBC編程時的差不多:_bstr_tstrConnect="DSN=datasource_name;Database=database_name;uid=user_name;pwd=password;";

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

定義_RecordsetPtr型變量,然后通過它調(diào)用Recordset對象的Open方法,即可打開一個數(shù)據(jù)集。所以Recordset對象與MFC中的CRecordset類類似,它也有當前記錄、當前記錄指針的概念。2022/11/3廣東工業(yè)大學計算機學院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方法非常重要,它的第一個參數(shù)可以是一個SQL語句、一個表的名字或一個命令對象等等;第二個參數(shù)就是前面建立的連接對象的指針。此外,用Connection和Command對象的Execute方法也能得到記錄集,但是只讀的。2022/11/3廣東工業(yè)大學計算機學院1104、讀取當前記錄的數(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對象的一個屬性(即該字段的值)。2022/11/3廣東工業(yè)大學計算機學院111要獲得Field對象的Value屬性的值可以直接用屬性名Value來引用它(如上例),但也可以調(diào)用Get方法,例如:CStringsName=(char*)(_bstr_t)(m_pRecordset->Fields->GetItem

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

從此例還可以看到,判斷是否到達記錄集的末尾,使用記錄集的adoEOF屬性,其值若為真即到了結(jié)尾,反之則未到。判斷是否到達記錄集開頭,則可用BOF屬性。2022/11/3廣東工業(yè)大學計算機學院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è)大學計算機學院113方法二:m_pRecordset->Fields->GetItem

(_variant_t(“姓名”))->PutValue(_bstr_t(“張三"));方法三:就是用定義綁定類的方法2022/11/3廣東工業(yè)大學計算機學院1146、添加記錄新記錄添加成功后,即自動成為當前記錄。AddNew方法有兩種形式,一個含有參數(shù),而另一個則不帶參數(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è)大學計算機學院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,因為添加后,ADO會自動調(diào)用它。

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

調(diào)用Recordset的Delete方法就行了,刪除的是當前記錄。要了解Delete的其它用法請查閱參考文獻。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è)大學計算機學院1178、使用帶參數(shù)的命令

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

本例中表示命令的語句就是一個SQL語句(SELECT語句)。SELECT語句中的問號?就代表參數(shù),如果要多個參數(shù),就多放幾個問號,每個問號代表一個參數(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

要注意命令對象必須與連接對象關聯(lián)起來才能起作用,本例中將命令對象的ActiveConnection屬性設置為連接對象的指針,即為此目的:Cmd1->ActiveConnection=Conn1;2022/11/3廣東工業(yè)大學計算機學院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)建一個參數(shù)對象,其中的長度參數(shù)(第三個)如果是固定長度的類型,就填-1,如果是字符串等可變長度的就填其實際長度。Parameters是命令對象的一個容器,它的Append方法就是把創(chuàng)建的參數(shù)對象追加到該容器里。Append進去的參數(shù)按先后順序與SQL語句中的問號從左至右一一對應。2022/11/3廣東工業(yè)大學計算機學院120(3).執(zhí)行命令打開記錄集//OpenRecordsetObject

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

但要注意,用Command和Connection對象的Execute方法得到的Recordset是只讀的。因為在打開Recordset之前,我們無法設置它的LockType屬性(其默認值為只讀)。而在打開之后設置LockType不起作用。2022/11/3廣東工業(yè)大學計算機學院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è)大學計算機學院1229、響應ADO的通知事件

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

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

為了響應_Connection的通知事件,應該從ConnectionEventsVt接口派生出一個類: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è)大學計算機學院124(2).實現(xiàn)每一個事件的處理函數(shù)(凡是帶raw_前綴的方法都把它實現(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)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論