C++第9章 數(shù)據(jù)庫編程_第1頁
C++第9章 數(shù)據(jù)庫編程_第2頁
C++第9章 數(shù)據(jù)庫編程_第3頁
C++第9章 數(shù)據(jù)庫編程_第4頁
C++第9章 數(shù)據(jù)庫編程_第5頁
已閱讀5頁,還剩45頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第9章

數(shù)據(jù)庫編程

(DatabaseProgramming)主講教師:劉懷廣

lhg81219@163.comVisualC++6.0為用戶提供了ODBC(開放數(shù)據(jù)庫連接)

、DAO(數(shù)據(jù)訪問對(duì)象)及OLEDB(OLE數(shù)據(jù)庫)三種數(shù)據(jù)庫方式。這三種方式中最簡(jiǎn)單也最常用的是ODBC,因此本章先來重點(diǎn)介紹MFC的ODBC編程方法和技巧,然后介紹基于OLEDB的ADO(ActiveXDataObjects,ActiveX數(shù)據(jù)對(duì)象)技術(shù),最后介紹一些用于數(shù)據(jù)庫的ActiveX控件。數(shù)據(jù)庫概述9.1MFCODBC數(shù)據(jù)庫概述ODBC是一種使用SQL的程序設(shè)計(jì)接口,使用ODBC能使用戶編寫數(shù)據(jù)庫應(yīng)用程序變得容易簡(jiǎn)單,避免了與數(shù)據(jù)源相連接的復(fù)雜性。MFC的ODBC數(shù)據(jù)庫類CDatabase(數(shù)據(jù)庫類)、CRecordSet(記錄集類)和CRecordView(記錄視圖類)可為用戶管理數(shù)據(jù)庫提供了切實(shí)可行的解決方案。9.1.1數(shù)據(jù)庫基本概念1.數(shù)據(jù)庫和數(shù)據(jù)庫管理系統(tǒng)DBMS

數(shù)據(jù)庫是指以一定的組織形式存放在計(jì)算機(jī)存儲(chǔ)介質(zhì)上的相互關(guān)聯(lián)的數(shù)據(jù)的集合。DBMS:包括數(shù)據(jù)庫的建立和記錄的輸入、修改、檢索、顯示、刪除和統(tǒng)計(jì)等。流行的DBMS都提供了一個(gè)SQL接口。9.1.1數(shù)據(jù)庫基本概念2.SQL(StructuredQueryLanguage)

DBMS中訪問和操作的語言,SQL(結(jié)構(gòu)化查詢語言)語句分為兩類:

DDL(DataDefinitionLanguage,數(shù)據(jù)定義語言)語句,它是用來創(chuàng)建表、索引等;

DML(DataManipulationLanguage,數(shù)據(jù)操作語言)語句,這些語句是用來讀取數(shù)據(jù)、更新數(shù)據(jù)和執(zhí)行其他類似操作的語句。

DCL(DataControlLanguage,數(shù)據(jù)控制語言)包括數(shù)據(jù)庫用戶賦權(quán),廢除用戶訪問權(quán)限,提交當(dāng)前事務(wù),中止當(dāng)前事務(wù)如:GRANT,REVOKE,COMMIT,ROLLBACK9.1.2常用的SQL語句1.SELECT

select_listFROMtable_list[WHEREcondition]

如:SELECT姓名FROM學(xué)生WHERE成績(jī)>802.INSERTINTO

table_name[field_name]VALUES(expression1,expression2,..)

如:INSERTINTO學(xué)生(姓名,成績(jī))VALUES(‘張三’,60)3.UPDATE

table_nameSETField_name1=expresion1,Field_name2=expresion2…

如:UPDATE學(xué)生SET成績(jī)=60WHERE姓名=‘張三’4.DELETE

table_name[WHEREcondition]

如:DELETE學(xué)生WHERE成績(jī)<603.ODBC、DAO和OLEDB

ODBC提供了應(yīng)用程序接口(API),使得任何一個(gè)數(shù)據(jù)庫都可以通過ODBC驅(qū)動(dòng)器與指定的DBMS相聯(lián)。

DAO使用Jet數(shù)據(jù)庫引擎形成一系列的數(shù)據(jù)訪問對(duì)象:數(shù)據(jù)庫對(duì)象、表和查詢對(duì)象、記錄集對(duì)象等。

OLEDB提供一個(gè)統(tǒng)一的數(shù)據(jù)訪問接口,使得應(yīng)用程序可以使用同樣的方法訪問各種數(shù)據(jù),而不用考慮數(shù)據(jù)的具體存儲(chǔ)地點(diǎn)、格式或類型。9.1.1數(shù)據(jù)庫基本概念4.ADO(ActiveXDataObjects)

ADO是目前比較流行的客戶端數(shù)據(jù)庫編程技術(shù)。ADO技術(shù)基于COM(ComponentObjectModel,組件對(duì)象模型),是遠(yuǎn)程數(shù)據(jù)存取的發(fā)展方向。9.1.1數(shù)據(jù)庫基本概念A(yù)DO是MS為最新和最強(qiáng)大的數(shù)據(jù)訪問接口OLEDB而設(shè)計(jì),是一個(gè)便于使用的應(yīng)用程序?qū)咏涌?。ADO是一種面向?qū)ο蟮?、與語言無關(guān)的(Language_Neutral)數(shù)據(jù)訪問應(yīng)用編程接口。它對(duì)OLEDBAPI進(jìn)行封裝,實(shí)現(xiàn)對(duì)數(shù)據(jù)的高層訪問,同時(shí)它也提供了多語言的訪問技術(shù),此外,由于ADO提供了訪問自動(dòng)化接口,它也支持腳本語言。ADO最主要的優(yōu)點(diǎn)在于易于使用、速度快、內(nèi)存支出少和磁盤遺跡小。ADO是用來訪問OLEDB的數(shù)據(jù)庫技術(shù)。在模型層次上它基于OLEDB,但在應(yīng)用上又高于OLEDB,因此它簡(jiǎn)化了對(duì)對(duì)象模型的操作,并且不依賴于對(duì)象之間的相互層次關(guān)系。

ODBC數(shù)據(jù)庫應(yīng)用程序(Application):用宿主語言和ODBC函數(shù)編寫的應(yīng)用程序用于訪問數(shù)據(jù)庫。其主要任務(wù)是管理安裝的ODBC驅(qū)動(dòng)程序和管理數(shù)據(jù)源。驅(qū)動(dòng)程序管理器(DriverManager):驅(qū)動(dòng)程序管理器包含在ODBC32.DLL中,對(duì)用戶是透明的。其任務(wù)是管理ODBC驅(qū)動(dòng)程序,為應(yīng)用程序加載、調(diào)用和卸載DB驅(qū)動(dòng)程序,是ODBC中最重要的部件。DB驅(qū)動(dòng)程序(DBMSDriver):是一些DLL,提供了ODBC和數(shù)據(jù)庫之間的接口。處理ODBC函數(shù),向數(shù)據(jù)源提交用戶請(qǐng)求執(zhí)行的SQL語句。數(shù)據(jù)源(DataSource):是DB驅(qū)動(dòng)程序與DBS之間連接的命名。數(shù)據(jù)源包含了數(shù)據(jù)庫位置和數(shù)據(jù)庫類型等信息,實(shí)際上是一種數(shù)據(jù)連接的抽象。9.1.1數(shù)據(jù)庫基本概念ODBC體系9.1.2MFCODBC向?qū)н^程用MFCAppWizard使用ODBC數(shù)據(jù)庫的一般過程是:①用Access或其他數(shù)據(jù)庫工具構(gòu)造一個(gè)數(shù)據(jù)庫;②在Windows中為剛才構(gòu)造的數(shù)據(jù)庫定義一個(gè)ODBC數(shù)據(jù)源;③在創(chuàng)建數(shù)據(jù)庫處理的文檔應(yīng)用程序向?qū)е羞x擇數(shù)據(jù)源;④設(shè)計(jì)界面,并使控件與數(shù)據(jù)表字段關(guān)聯(lián)。1.構(gòu)造數(shù)據(jù)庫

數(shù)據(jù)庫表與表之間的關(guān)系構(gòu)成了一個(gè)數(shù)據(jù)庫。作為示例,這里用MicrosoftAccess創(chuàng)建一個(gè)數(shù)據(jù)庫Student.mdb,其中暫包含一個(gè)數(shù)據(jù)表score,用來描述學(xué)生課程成績(jī)。在表中包括上、下兩部分,上部分是數(shù)據(jù)表的記錄內(nèi)容,下部分是數(shù)據(jù)表的結(jié)構(gòu)內(nèi)容。

表9.1學(xué)生課程成績(jī)表(score)及其表結(jié)構(gòu)圖8.1Windows2000的管理工具圖8.2ODBC數(shù)據(jù)源管理器2.創(chuàng)建ODBC數(shù)據(jù)源

Windows中的ODBC組件是出現(xiàn)在系統(tǒng)的“控制面板”管理工具中,如圖8.1所示。雙擊ODBC圖標(biāo)(在圖8.1中已圈定),進(jìn)入ODBC數(shù)據(jù)源管理器。在這里,用戶可以設(shè)置ODBC數(shù)據(jù)源的一些信息。其中,“用戶DSN”頁面是用來定義用戶自己在本地計(jì)算機(jī)使用的數(shù)據(jù)源名(DSN),如圖8.2所示。圖8.3“創(chuàng)建新數(shù)據(jù)源”對(duì)話框

圖8.4ODBCAccess安裝對(duì)話框

創(chuàng)建用戶DSN的過程如下:(1)單擊[添加]→彈出“創(chuàng)建新數(shù)據(jù)源”→選擇“MicrosoftAccessDriver”。(2)單擊[完成]→進(jìn)入指定驅(qū)動(dòng)程序的安裝對(duì)話框→單擊[選擇]將前面創(chuàng)建的數(shù)據(jù)庫調(diào)入→在數(shù)據(jù)源名輸入“DatabaseExampleForVC++”,結(jié)果如圖8.4所示。(3)單擊[確定]按鈕,剛才創(chuàng)建的用戶數(shù)據(jù)源被添加在“ODBC數(shù)據(jù)源管理器”的“用戶數(shù)據(jù)源”列表中。如圖8.5所示。圖8.5用戶數(shù)據(jù)源列表9.1.2MFCODBC向?qū)н^程9.1.2MFCODBC向?qū)н^程表9.2MFC支持?jǐn)?shù)據(jù)庫的不同選項(xiàng)3.在MFCAppWizard中選擇數(shù)據(jù)源1)創(chuàng)建一個(gè)支持?jǐn)?shù)據(jù)庫的文檔應(yīng)用程序Ex_ODBC。2)在向?qū)У牡?步對(duì)話框中加入數(shù)據(jù)庫的支持。其中各選項(xiàng)的含義如表9.2所示。3)選中“數(shù)據(jù)庫查看使用文件支持”項(xiàng),單擊[DataSource]按鈕,彈出“DatabaseOptions”對(duì)話框,從中選擇ODBC的數(shù)據(jù)源“DatabaseExampleForVC++”,如圖9.7所示。圖9.7“DatabaseOptions”對(duì)話框

9.1.2MFCODBC向?qū)н^程(4)保留其他默認(rèn)選項(xiàng),單擊[OK]按鈕,彈出“SelectDatabaseTables”對(duì)話框,從中選擇要使用的表score。(5)單擊[OK]按鈕,又回到了向?qū)У牡?步對(duì)話框。(6)單擊[完成]按鈕。開發(fā)環(huán)境自動(dòng)打開表單視圖CEx_ODBCView的對(duì)話框資源模板IDD_EX_ODBC_FORM以及相應(yīng)的對(duì)話框編輯器。(7)編譯并運(yùn)行,結(jié)果如圖8.9所示。記錄瀏覽按鈕圖8.9Ex_ODBC運(yùn)行結(jié)果9.1.2MFCODBC向?qū)н^程4.設(shè)計(jì)瀏覽記錄界面在上面的Ex_ODBC中,MFC為用戶自動(dòng)創(chuàng)建了用于瀏覽數(shù)據(jù)表記錄的工具按鈕和相應(yīng)的“記錄”菜單項(xiàng)。若在表單視圖CEx_ODBCView中添加控件并與表的字段相關(guān)聯(lián),就可以根據(jù)表的當(dāng)前記錄位置顯示相應(yīng)的數(shù)據(jù)。其步驟如下。(1)按照?qǐng)D所示的布局,為表單對(duì)話框資源模板添加控件。9.1.2MFCODBC向?qū)н^程表8.3表單對(duì)話框控件及屬性(2)按快捷鍵Ctrl+W→切換到MemberVariables頁面→為上述控件添加相關(guān)聯(lián)的數(shù)據(jù)成員。與以往添加控件變量不同的是,這里添加的控件變量都是由系統(tǒng)自動(dòng)定義的,并與數(shù)據(jù)庫表字段相關(guān)聯(lián)的。9.1.2MFCODBC向?qū)н^程表8.4控件變量(3)按照上一步驟的方法,為表8.4所示的其他控件依次添加相關(guān)聯(lián)的成員變量。需要說明的是,控件變量的范圍和大小應(yīng)與數(shù)據(jù)表中的字段一一對(duì)應(yīng)。(4)編譯運(yùn)行并測(cè)試。9.1.2MFCODBC向?qū)н^程9.1.3ODBC數(shù)據(jù)表綁定更新圖8.14“MFCClassWizard”(1)按快捷鍵Ctrl+W,切換到“MemberVariables”頁面。(2)在“Classname”的下拉列表中選擇“CEx_ODBCSet”,[UpdateColumns]和[BindAll]按鈕被激活,如圖8.14所示。圖8.15“DatabaseOptions”

圖8.16“SelectDatabaseTables”(3)[UpdateColumns]按鈕,彈出“DatabaseOptions”對(duì)話框,選擇ODBC數(shù)據(jù)源“DatabaseExampleForVC++”,如圖8.15所示。(4)單擊[OK],如圖8.16的“SelectDatabaseTables”,選擇要使用的表。9.1.3ODBC數(shù)據(jù)表綁定更新(5)單擊[OK],又回到MFCClassWizard界面。(6)單擊[BindAll]按鈕,MFCWizard將自動(dòng)為字段落添加相關(guān)聯(lián)的變量。9.1.3ODBC數(shù)據(jù)表綁定更新9.2MFCODBC應(yīng)用編程

使用MFC所供的ODBC類:CDatabase(數(shù)據(jù)庫類)、CRecordSet(記錄集類)和CRecordView(可視記錄集類)。

CDatabase類:提供對(duì)數(shù)據(jù)源的連接,通過它可以對(duì)數(shù)據(jù)源進(jìn)行操作;

CRecordSet類:為用戶提供了對(duì)表記錄進(jìn)行操作的許多功能,如查詢記錄、添加記錄、刪除記錄、修改記錄等。

CRecordView類:控制并顯示數(shù)據(jù)庫記錄,該視圖是直接連到一個(gè)CRecordSet對(duì)象的表單視圖。9.2MFCODBC介紹MFCODBC是MFC對(duì)ODBC進(jìn)行的封裝,以簡(jiǎn)化對(duì)ODBCAPI的

調(diào)用,從而實(shí)現(xiàn)面向?qū)ο蟮臄?shù)據(jù)庫編程接口.MFCODBC的封裝主要開發(fā)了CDatabase類和CRecordSet類

CDatabase類

CDatabase類用于應(yīng)用程序建立同數(shù)據(jù)源的連接。CDatabase類中包含一個(gè)m_hdbc變量,它代表了數(shù)據(jù)源的連接句柄。如果要建立CDatabase類的實(shí)例,應(yīng)先調(diào)用該類的構(gòu)造函數(shù),再調(diào)用Open函數(shù),通過調(diào)用,初始化環(huán)境變量,并執(zhí)行與數(shù)據(jù)源的連接。在通過Close函數(shù)關(guān)閉數(shù)據(jù)源。

CDatabase類提供了對(duì)數(shù)據(jù)庫進(jìn)行操作的函數(shù)及事務(wù)操作。

CRecordSet類

CRecordSet類定義了從數(shù)據(jù)庫接收或者發(fā)送數(shù)據(jù)到數(shù)據(jù)庫的成員變量,以實(shí)現(xiàn)對(duì)數(shù)據(jù)集的數(shù)據(jù)操作。

CRecordSet類的成員變量m_hstmt代表了定義該記錄集的SQL語句句柄,m_nFields為記錄集中字段的個(gè)數(shù),m_nParams為記錄集所使用的參數(shù)個(gè)數(shù)。

CRecordSet的記錄集通過CDatabase實(shí)例的指針實(shí)現(xiàn)同數(shù)據(jù)源的連接,即CRecordSet的成員變量m_pDatabase.

MFCODBC編程更適合于界面型數(shù)據(jù)庫應(yīng)用程序的開發(fā),但由于CDatabase類和CRecordSet類提供的數(shù)據(jù)庫操作函數(shù)有限,支持的游標(biāo)類型也有限,限制了高效的數(shù)據(jù)庫開發(fā)。在編程層次上屬于高級(jí)編程。

9.2.1查詢記錄圖8.18要添加的控件

CRecordSet類的成員變量m_strFilter、m_strSort和成員函數(shù)Open可以對(duì)表進(jìn)行記錄的查詢和排序。在前面的Ex_ODBC的表單中添加一個(gè)編輯框和一個(gè)[查詢]按鈕:?jiǎn)螕鬧查詢]按鈕,將按編輯框中的學(xué)號(hào)內(nèi)容對(duì)數(shù)據(jù)表進(jìn)行查詢,并將查找到的記錄顯示在前面添加的控件中。具體過程如下:(1)打開Ex_ODBC應(yīng)用程序的表單資源,按圖8.18所示的布局:添加編輯框ID為IDC_EDIT_QUERY,“查詢”按鈕ID為IDC_BUTTON_QUERY。9.2.1查詢記錄(2)用MFCClassWizard為控件IDC_EDIT_QUERY添加Cstring型的成員變量m_strQuery。(3)在CEx_ODBCView類中添加按鈕控件IDC_BUTTON_QUERY的BN_CLICKED消息映射,并在映射函數(shù)中添加下列代碼:(4)編譯運(yùn)行并測(cè)試,結(jié)果如圖所示。圖8.19查詢記錄voidCEx_ODBCView::OnButtonQuery(){ UpdateData();

m_strQuery.TrimLeft();//刪除字符串左邊的空格及控制字符如(\n\t空格等)

if(m_strQuery.IsEmpty()){MessageBox("要查詢的學(xué)號(hào)不能為空!");return;} if(m_pSet->IsOpen())m_pSet->Close();//如果記錄集打開,則先關(guān)閉

m_pSet->m_strFilter.Format("studentno='%s'",m_strQuery);

//studentno是score表的字段名,用來指定查詢條件

m_pSet->m_strSort="course";

//course是score表的字段名,用來按course字段從小到大排序

m_pSet->Open();//打開記錄集

if(!m_pSet->IsEOF())//如果打開記錄集有記錄

UpdateData(FALSE);//自動(dòng)更新表單中控件顯示的內(nèi)容

else MessageBox("沒有查到你要找的學(xué)號(hào)記錄!");}

m_strFilter和m_strSort是CRecordSet的成員變量,用來執(zhí)行條件查詢和結(jié)果排序。其中,m_strFilter稱為“過濾字符串”,相當(dāng)于SQL語句中WHERE后的條件串;而m_strSort稱為“排序字符串”,相當(dāng)于SQL語句中ORDERBY后的字符串。若字段的數(shù)據(jù)類型是文本,則需要在m_strFilter字符串中將單引號(hào)將查詢的內(nèi)容括起來,對(duì)于數(shù)字,則不需要用單引號(hào)。9.2.1查詢記錄9.2.2編輯記錄m_pSet->AddNew(); //在表的末尾增加新記錄m_pSet->SetFieldNull(&(m_pSet->m_studentno),FALSE);//設(shè)定m_studentno值不為空(NULL)m_pSet->m_studentno="21010503"; //輸入新的字段值m_pSet->Update(); //將新記錄存入數(shù)據(jù)庫m_pSet->Requery(); //刷新記錄集,這在快照集方式下是必須的

CRecordSet類為用戶提供了成員函數(shù)用來添加記錄、刪除記錄和修改記錄等。1.增加記錄使用AddNew函數(shù),但要求數(shù)據(jù)庫必須是以“可增加”的方式打開的。9.2.2編輯記錄2.刪除記錄直接使用CRecordSet::Delete刪除記錄。要使操作有效,還需要移動(dòng)記錄函數(shù)CRecordsetStatus

status;m_pSet->GetStatus(status);//獲取當(dāng)前記錄集狀態(tài)m_pSet->Delete(); //刪除當(dāng)前記錄if(status.m_lCurrentRecord==0)

m_pSet->MoveNext(); //若當(dāng)前記錄索引號(hào)為0(0表示第一條記錄) //則下移一個(gè)記錄else

m_pSet->MoveFirst(); //移動(dòng)到第一個(gè)記錄處UpdateData(FALSE);3.修改記錄函數(shù)CRecordSet::Edit可以用來修改記錄,例如:m_pSet->Edit(); //修改當(dāng)前記錄m_pSet->m_name=“杰克遜"; //修改當(dāng)前記錄字段值m_pSet->Update(); //將修改結(jié)果存入數(shù)據(jù)庫m_pSet->Requery();9.2.2編輯記錄4.撤消操作如果用戶在進(jìn)行增加或者修改記錄后,希望放棄當(dāng)前操作,則在調(diào)用CRecordSet::Update()函數(shù)之前調(diào)用CRecordSet::Move(AFX_MOVE_REFRESH)來撤消操作,便可恢復(fù)在增加或修改操作之前的當(dāng)前記錄。9.2.2編輯記錄9.2.3字段操作

CRecordSet類中的成員變量m_nFields

:用于保存數(shù)據(jù)表的字段個(gè)數(shù)。成員函數(shù)GetODBCFieldInfo及GetFieldValue可以簡(jiǎn)化多字段的訪問操作。voidGetODBCFieldInfo(shortnIndex,CODBCFieldInfo&fieldinfo);

nIndex:指定字段索引號(hào),0表示第一個(gè)字段,1表示第二個(gè)字段,以此類推。

fieldinfo是CODBCFieldInfo結(jié)構(gòu)參數(shù),用來表示字段信息。9.2.3字段操作struct

CODBCFieldInfo{

CString

m_strName; //字段名

SWORDm_nSQLType;//字段的SQL數(shù)據(jù)類型

UDWORDm_nPrecision;//字段的文本大小或數(shù)據(jù)大小

SWORDm_nScale; //字段的小數(shù)點(diǎn)位數(shù)

SWORDm_nNullability;//字段接受空值(NULL)能力};9.2.3字段操作struct

CRecordsetStatus{longm_lCurrentRecord; //當(dāng)前記錄的索引,0表示第一個(gè)記錄,1表示第二個(gè)記錄,依次類推。但-1表示在第一個(gè)記錄之前,-2表示不確定。

BOOLm_bRecordCountFinal; //記錄總數(shù)是否是最終結(jié)果};voidGetFieldValue(shortnIndex,CString&strValue);nIndex:指定字段索引號(hào),strValue:返回字段的內(nèi)容。longGetRecordCount()const;//獲得表中的記錄總數(shù)voidGetStatus(CRecordsetStatus&rStatus)const;//當(dāng)前記錄的索引表9.8課程信息表(course)及其表結(jié)構(gòu)[例Ex_Field]字段的編程操作1.為Student.mdb添加一個(gè)數(shù)據(jù)表course:用MicrosoftAccess為數(shù)據(jù)庫Student.mdb添加一個(gè)數(shù)據(jù)表course,如表9.8所示。表中上部分是數(shù)據(jù)表的記錄內(nèi)容,下部分是數(shù)據(jù)表的結(jié)構(gòu)內(nèi)容。#ifndef_AFX_NO_AFXCMN_SUPPORT#include<afxcmn.h>//MFCsupportforWindowsCommonControls#endif//_AFX_NO_AFXCMN_SUPPORT#include<afxdb.h>2.文檔程序添加ODBC的支持(1)創(chuàng)建一個(gè)默認(rèn)的單文檔應(yīng)用程序Ex_Field,但在向?qū)У牡?步將CEx_FieldView的基類由默認(rèn)的CView選擇為CListView類。(2)將項(xiàng)目工作區(qū)窗口切換到FileView頁面,展開HeaderFiles所有項(xiàng),雙擊stdafx.h,打開該文件。(3)在stdafx.h中添加ODBC數(shù)據(jù)庫支持的頭文件包含#include<afxdb.h>:3.創(chuàng)建數(shù)據(jù)表score的CRecordSet派生類(1)按快捷鍵Ctrl+W→單擊[AddClass],從彈出的下拉菜單中選擇“New”。(2)在彈出的“AddClass”對(duì)話框中指定CRecordSet的派生類CCourseSet。圖8.23定義新的CRecordSet派生類(3)單擊[OK],彈出“DatabaseOptions”。從中選擇ODBC的數(shù)據(jù)源“DatabaseExampleForVC++”,單擊[OK],彈出“SelectDatabaseTables”對(duì)話框,從中選擇要使用的表course。(4)單擊[OK]回到MFCClassWizard界面,單擊[確定],系統(tǒng)自動(dòng)為用戶生成CCourseSet類所需要的代碼。(5)在CEx_FieldView::PreCreateWindow函數(shù)中添加修改列表視圖風(fēng)格的代碼:BOOLCEx_FieldView::PreCreateWindow(CREATESTRUCT&cs){

cs.style&=~LVS_TYPEMASK;

cs.style|=LVS_REPORT;//報(bào)表方式

returnCListView::PreCreateWindow(cs);}(6)在CEx_FieldView::OnInitialUpdate函數(shù)中添加下列代碼:voidCEx_FieldView::OnInitialUpdate(){

CListView::OnInitialUpdate();

CListCtrl&m_ListCtrl=GetListCtrl();//獲取內(nèi)嵌在列表視圖中的列表控件

CCourseSet

cSet;

cSet.Open(); //打開記錄集

CODBCFieldInfofield;

//創(chuàng)建列表頭

for(UINTi=0;i<cSet.m_nFields;i++) { cSet.GetODBCFieldInfo(i,field); m_ListCtrl.InsertColumn(i,field.m_strName,LVCFMT_LEFT,100); }//添加列表項(xiàng)

int

nItem=0;

CString

str; while(!cSet.IsEOF()) {for(UINTi=0;i<cSet.m_nFields;i++){cSet.GetFieldValue(i,str); if(i==0)m_ListCtrl.InsertItem(nItem,str); else m_ListCtrl.SetItemText(nItem,i,str); }

nItem++;

cSet.MoveNext(); }

cSet.Close(); //關(guān)閉記錄集}(7)在Ex_FieldView.cpp文件的前面添加CCourseSet類的頭文件包含:

#include"Ex_FieldDoc.h"#include"Ex_FieldView.h"#include"CourseSet.h"(8)編譯運(yùn)行,結(jié)果如圖9.22所示。圖9.22Ex_Field第一次運(yùn)行結(jié)果4.在狀態(tài)欄中顯示當(dāng)前記錄號(hào)和記錄總數(shù)(1)在MainFrm.cpp文件中,向原來的indicators數(shù)組添加一個(gè)元素,用來在狀態(tài)欄上增加一個(gè)窗格:staticUINTindicators[]={ID_SEPARATOR,//第一個(gè)信息行窗格

ID_SEPARATOR,//第二個(gè)信息行窗格

ID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,};voidDispRecNum(CCourseSet*pSet){ CString

str;

CMainFrame*pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;//獲得主框架窗口的指針

CStatusBar*pStatus=&pFrame->m_wndStatusBar;//獲得主框架窗口中的狀態(tài)欄指針

if(pStatus){ CRecordsetStatus

rStatus;

pSet->GetStatus(rStatus);//獲得當(dāng)前記錄信息

str.Format("當(dāng)前記錄:%d總記錄:%d",1+rStatus.m_lCurrentRecord,pSet->GetRecordCount());

pStatus->SetPaneText(1,str); //更新第二個(gè)窗格的文本

}}//該函數(shù)先獲得狀態(tài)欄對(duì)象的指針,然后調(diào)用SetPaneText函數(shù)更新第二個(gè)窗格文本(2)在Ex_FieldView.cpp文件的前面添加一個(gè)全局函數(shù)DispRecNum成員函數(shù)(3)在CEx_ODBCView的OnInitialUpdate函數(shù)處添加下列代碼:voidCEx_FieldView::OnInitialUpdate(){…

CString

str;while(!cSet.IsEOF()) {… }::DispRecNum(&cSet);

cSet.Close(); //關(guān)閉記錄集}(4)在Ex_ODBCView.cpp文件的開始處增加下列語句:

#include"Ex_FieldDoc.h" #include"Ex_FieldView.h" #include"CourseSet.h" #include"MainFrm.h"(5)將MainFrm.h文件中的保護(hù)型變量m_wndStatusBar變成公共變量。(6)編譯運(yùn)行并測(cè)試,結(jié)果如圖8.25所示。顯示的記錄信息圖8.25Ex_Field最后運(yùn)行結(jié)果9.2.4多表處理圖9.24Ex_Student運(yùn)行結(jié)果

下面的示例在一個(gè)對(duì)話框中用兩個(gè)控件來進(jìn)行學(xué)生課程成績(jī)信息的相關(guān)操作,如圖9.24所示,左邊是樹視圖,用來顯示學(xué)生成績(jī)、專業(yè)和班級(jí)號(hào)三個(gè)層次信息,單擊班級(jí)號(hào),所有該班級(jí)的學(xué)生課程成績(jī)信息將在右邊的列表視圖中顯示出來。[例Ex_Student]多表處理1.為數(shù)據(jù)庫Student.mdb添加一個(gè)數(shù)據(jù)表student用MicrosoftAccess為數(shù)據(jù)庫Student.mdb添加一個(gè)數(shù)據(jù)表student,如表8.6所示。表中上部分是數(shù)據(jù)表的記錄內(nèi)容,下部分是數(shù)據(jù)表的結(jié)構(gòu)內(nèi)容。表8.6學(xué)生基本信息表(student)及其表結(jié)構(gòu)2.創(chuàng)建并設(shè)計(jì)對(duì)話框應(yīng)用程序(1)創(chuàng)建一個(gè)默認(rèn)的基于對(duì)話框應(yīng)用程序Ex_Student。(2)刪除[取消]按鈕和默認(rèn)的靜態(tài)文本控件。(3)對(duì)話框的標(biāo)題改為“處理多表”,將[確定]按鈕的標(biāo)題文本改為“退出”。(4)參看圖8.26,添加一個(gè)樹控件,在其屬性對(duì)話框中,選中“有按鈕”、“有行(Lines,線)”、“Linesatroot”和“總是顯示選擇”屬性。(5)添加一個(gè)列表控件,在其屬性對(duì)話框中,將“查看”屬性選為“Report”。(6)用MFCClassWizard在CEx_StudentDlg類中,添加樹控件的控件變量為m_treeCtrl,添加列表控件的控件變量為m_listCtrl。3.添加對(duì)MFCODBC的支持及記錄集在stdafx.h文件中添加ODBC數(shù)據(jù)庫支持的頭文件包含

#include<afxdb.h>

用MFCClassWizard為數(shù)據(jù)表student、course和score分別創(chuàng)建CRecordSet派生類CStudentSet、CCourseSet和CScoreSet。4.完善左邊樹控件的代碼(1)為CEx_StudentDlg類添加一個(gè)成員函數(shù)FindTreeItem,用來查找指定節(jié)點(diǎn)下是否有指定節(jié)點(diǎn)文本的子節(jié)點(diǎn),該函數(shù)的代碼如下:HTREEITEMCEx_StudentDlg::FindTreeItem(HTREEITEM

hParent,CString

str){HTREEITEMhNext;

CString

strItem;

hNext=m_treeCtrl.GetChildItem(hParent);while(hNext!=NULL){strItem=m_treeCtrl.GetItemText(hNext);if(strItem==str)returnhNext;elsehNext=m_treeCtrl.GetNextItem(hNext,TVGN_NEXT);}returnNULL;}(2)為CEx_StudentDlg類添加CImageList成員變量m_ImageList。(3)在CEx_StudentDlg::OnInitDialog中添加下列代碼:BOOLCEx_StudentDlg::OnInitDialog(){…

SetIcon(m_hIcon,FALSE); //Setsmalliconm_ImageList.Create(16,16,ILC_COLOR8|ILC_MASK,2,1);

m_treeCtrl.SetImageList(&m_ImageList,TVSIL_NORMAL);SHFILEINFOfi; //定義一個(gè)文件信息結(jié)構(gòu)變量

SHGetFileInfo("C:\\Windows",0,&fi,sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON);//獲取文件夾圖標(biāo)

m_ImageList.Add(fi.hIcon);//獲取打開文件夾圖標(biāo)

SHGetFileInfo("C:\\Windows",0,&fi,sizeof(SHFILEINFO),HGFI_ICON|SHGFI_SMALLICON|SHGFI_OPENICON);m_ImageList.Add(fi.hIcon);HTREEITEMhRoot,hSpec,hClass;

hRoot=m_treeCtrl.InsertItem("學(xué)生成績(jī)",0,1);

CStudentSet

sSet;

sSet.m_strSort=“special”; //按專業(yè)排序

sSet.Open(); while(!sSet.IsEOF()){

hSpec=FindTreeItem(hRoot,sSet.m_special);//查找是否有重復(fù)的專業(yè)節(jié)點(diǎn)

if(hSpec==NULL)//若沒有重復(fù)的專業(yè)節(jié)點(diǎn)

hSpec=m_treeCtrl.InsertItem(sSet.m_special,0,1,hRoot);

hClass=FindTreeItem(hSpec,sSet.m_studentno.Left(6)); //查找是否有重復(fù)的班級(jí)節(jié)點(diǎn)

if(hClass==NULL)//若沒有重復(fù)的班級(jí)節(jié)點(diǎn)

hClass=m_treeCtrl.InsertItem(sSet.m_studentno.Left(6),0,1,hSpec);

sSet.MoveNext(); }

sSet.Close(); returnTRUE;//returnTRUEunlessyousetthefocustoacontrol}(4)在Ex_StudentDlg.cpp文件的前面添加記錄集類的包含文件:

#include"Ex_StudentDlg.h"#include"StudentSet.h"#include"ScoreSet.h"#include"CourseSet.h"(5)編譯運(yùn)行,結(jié)果如圖8.27所示。圖8.27Ex_Student第一次運(yùn)行結(jié)果5.完善右邊列表控件的代碼(1)在CEx_StudentDlg::OnInitDialog函數(shù)中添加代碼,創(chuàng)建列表標(biāo)題頭BOOLCEx_StudentDlg::OnInitDialog(){…

sSet.Close();//設(shè)置列表頭

CString

strHeader[]={"學(xué)號(hào)","姓名","課程號(hào)","課程所屬專業(yè)", "課程名稱","課程類別","開課學(xué)期","課時(shí)數(shù)","學(xué)分","成績(jī)"};

int

nLong[]={80,80,80,180,180,80,80,80,80,80};for(int

nCol=0;nCol<sizeof(strHeader)/sizeof(CString);nCol++)

m_listCtrl.InsertColumn(nCol,strHeader[nCol],LVCFMT_LEFT,nLong[nCol]);returnTRUE;//returnTRUEunlessyousetthefocustoacontrol}(2)為CEx_StudentDlg類添加一個(gè)成員函數(shù)DispScoreAndCourseInfo,用來根據(jù)指定的條件在列表控件中用報(bào)表形式顯示學(xué)生成績(jī)的所有信息。voidCEx_StudentDlg::DispScoreAndCourseInfo(CString

strFilter){ m_listCtrl.DeleteAllItems();//刪除所有的列表項(xiàng)

CScoreSet

sSet;

sSet.m_strFilter=strFilter;//設(shè)置過濾條件

sSet.Open(); //打開score表

int

nItem=0;

CString

str; while(!sSet.IsEOF()) {m_listCtrl.InsertItem(nItem,sSet.m_studentno);//插入學(xué)號(hào)

//根據(jù)score表中的studentno(學(xué)號(hào))獲取student表中的"姓名"

CStudentSet

uSet;

uSet.m_strFilter.Format("studentno='%s'",sSet.m_studentno);

uSet.Open(); if(!uSet.IsEOF())m_listCtrl.SetItemText(nItem,1,uSet.m_studentname);

uSet.Close();

m_listCtrl.SetItemText(nItem,2,sSet.m_course);

//根據(jù)score表中的course(課程號(hào))獲取course表中的課程信息

CCourseSet

cSet;

cSet.m_strFilter.Format("courseno='%s'",sSet.m_course);

cSet.Open(); UINTi=7; if(!cSet.IsEOF()){for(i=1;i<cSet.m_nFields;i++){cSet.GetFieldValue(i,str);//獲取指定字段值

m_listCtrl.SetItemText(nItem,i+2,str); } }

cSet.Close(); str.Format("%0.1f",sSet.m_score);

m_listCtrl.SetItemText(nItem,i+2,str);

sSet.MoveNext();

nItem++; } if(sSet.IsOpen())sSet.Close();}(3)編譯并運(yùn)行,結(jié)果如圖8.28所示。圖8.28Ex_Student第二次運(yùn)行結(jié)果voidCEx_StudentDlg::OnSelchangedTree1(NMHDR*pNMHDR,LRESULT*pResult){ NM_TREEVIEW*pNMTreeView=(NM_TREEVIEW*)pNMHDR; HTREEITEMhSelItem=pNMTreeView->itemNew.hItem;//獲取當(dāng)前選擇節(jié)點(diǎn)

//如果當(dāng)前的節(jié)點(diǎn)沒有子節(jié)點(diǎn),那說明該節(jié)點(diǎn)是班級(jí)號(hào)節(jié)點(diǎn)

if(m_treeCtrl.GetChildItem(hSelItem)==NULL){ CString

strSelItem,str;

strSelItem=m_treeCtrl.GetItemText(hSelItem);

str.Format("studentnoLIKE'%s%%'",strSelItem.Left(6));

DispScoreAndCourseInfo(str); } *pResult=0;}6.完善兩控件的關(guān)聯(lián)代碼從上圖中可以看出,學(xué)生成績(jī)還沒有顯示出來,下面將實(shí)現(xiàn)單擊左邊的班級(jí)號(hào),在右邊視圖中顯示該班級(jí)的所有學(xué)生成績(jī)信息。(1)CEx_StudentDlg類添加TVN_SELCHANGED消息處理:

代碼中,調(diào)用DispScoreAndCourseInfo

函數(shù)的參數(shù)是用來設(shè)置數(shù)據(jù)表(記錄集)打開的過濾條件。str是類似內(nèi)容:“studentnoLIKE210101%”,它使得所有學(xué)號(hào)前面是210101的記錄被打開。%是SQL使用的通配符,由于%也是VisaulC++格式前導(dǎo)符,因?yàn)樵诖a中需要兩個(gè)%。(2)編譯運(yùn)行并測(cè)試。9.4ADO數(shù)據(jù)庫編程ADO最主要的優(yōu)點(diǎn):易于使用、速度快、內(nèi)存開銷小,它使用最少的網(wǎng)絡(luò)流量,并且在前端和數(shù)據(jù)源之間使用最少的層數(shù),它是一個(gè)輕量、高性能的接口。ADO實(shí)際上就是由一組Automation對(duì)象構(gòu)成的組件(COM),因此可以像使用其它任何Automation對(duì)象一樣使用ADO。ADO中最重要的對(duì)象有三個(gè):_ConnectionPtr、_CommandPtr和_RecordsetPtr,它們分別表示“連接”對(duì)象、“命令”對(duì)象和“記錄集”對(duì)象。9.4.1ADO編程的一般過程在MFC應(yīng)用程序中使用ADO數(shù)據(jù)庫的一般過程是:①COM庫的初始化;②添加對(duì)ADO的支持;③創(chuàng)建一個(gè)數(shù)據(jù)源連接;④對(duì)數(shù)據(jù)源中的數(shù)據(jù)庫進(jìn)行操作;⑤關(guān)閉數(shù)據(jù)源。1.COM庫的初始化

使用AfxOleInit()來初始化COM庫,這項(xiàng)工作通常在CWinApp::InitInstance()的重載函數(shù)中完成。9.4.1ADO編程的一般過程2.添加對(duì)ADO的支持

ADO編程有三種方式:使用預(yù)處理指令#import、使用MFC中的CIDispatchDriver和直接使用COM提供的API。這三種方式中,第一種最為簡(jiǎn)便,故這里采有用這種方法。

#import"c:\programfiles\commonfiles\system\ado\msado15.dll"no_namespace

rename("EOF","adoEOF")

幾點(diǎn)說明:(1)您的環(huán)境中msado15.dll不一定在這個(gè)目錄下,請(qǐng)按實(shí)際情況修改(2)在編譯的時(shí)候肯能會(huì)出現(xiàn)如下警告,對(duì)此微軟在MSDN中作了說明,并建議我們不要理會(huì)這個(gè)警告。msado15.tlh(405):warningC4146:unaryminusoperatorappliedtounsignedtype,resultstillunsigned9.4.1_ConnectionPtr初始化:Connection

::CreateInstance("ADODB.Connection");

或Connection

::CreateInstance(__uuidof(Connection))_ConnectionPtr是Connection類的一個(gè)智能指針,返回一個(gè)記錄集或一個(gè)空指針。通常使用它來創(chuàng)建一個(gè)數(shù)據(jù)連接或執(zhí)行一條不返回任何結(jié)果的SQL語句,如一個(gè)存儲(chǔ)過程。使用_ConnectionPtr接口返回一個(gè)記錄集不是一個(gè)好的使用方法。通常同CDatabase一樣,使用它創(chuàng)建一個(gè)數(shù)據(jù)連接,然后使用其它對(duì)象執(zhí)行數(shù)據(jù)輸入輸出操作。打開連接:Connection::Open(

const

_variant_t

&

Source,

const

_variant_t

&

ActiveConnection,

enum

CursorTypeEnum

CursorType,

enum

LockTypeEnum

LockType,

long

Options

)關(guān)閉連接:Connection::Close(

)釋放指針:Connection::Release(

)Connection::Open(

const

_variant_t

&

Source,const

_variant_t

&

ActiveConnection,

enum

CursorTypeEnum

CursorType,enum

LockTypeEnum

LockType,

long

Options

)①Source是數(shù)據(jù)查詢字符串

②ActiveConnection是已經(jīng)建立好的連接(需要用Connection對(duì)象指針來構(gòu)造一個(gè)_variant_t對(duì)象)

③CursorType光標(biāo)類型,它可以是以下值之一,請(qǐng)看這個(gè)枚舉結(jié)構(gòu):

enum

CursorTypeEnum

{adOpenUnspecified

=

-1,///不作特別指定

adOpenForwardOnly

=

0,///前滾靜態(tài)光標(biāo)。這種光標(biāo)只能向前瀏覽記錄集,比如用MoveNext向前滾動(dòng),這種方式可以提高瀏覽速度。但諸如BookMark,RecordCount,AbsolutePosition,AbsolutePage

都不能使用

adOpenKeyset

=

1,///采用這種光標(biāo)的記錄集看不到其它用戶的新增、刪除操作,但對(duì)于更新原有記錄的操作對(duì)你是可見的。

adOpenDynamic

=

2,///動(dòng)態(tài)光標(biāo)。所有數(shù)據(jù)庫的操作都會(huì)立即在各用戶記錄集上反應(yīng)出來。

adOpenStatic

=

3///靜態(tài)光標(biāo)。它為你的記錄集產(chǎn)生一個(gè)靜態(tài)備份,但其它用戶的新增、刪除、更新操作對(duì)你的記錄集來說是不可見的。};

④LockType鎖定類型,它可以是以下值之一,請(qǐng)看如下枚舉結(jié)構(gòu):

enum

LockTypeEnum

{adLockUnspecified

=

-1,///未指定

adLockReadOnly

=

1,///只讀記錄集

adLockPessimistic

=

2,悲觀鎖定方式。數(shù)據(jù)在更新時(shí)鎖定其它所有動(dòng)作,這是最安全的鎖定機(jī)制

adLockOptimistic

=

3,//樂觀鎖定方式。只有在你調(diào)用Update方法時(shí)才鎖定記錄。在此之前仍然可以做數(shù)據(jù)的更新、插入、刪除等動(dòng)作

adLockBatchOptimistic

=

4,樂觀分批更新。編輯時(shí)記錄不會(huì)鎖定,更改、插入及刪除是在批處理模式下完成。};

ConnectionString:連接字串,UserID:用戶名,Password:登錄密碼,Options是選項(xiàng),通常用于設(shè)置同步和異步等方式。_bstr_t是一個(gè)COM類,用于字符串BSTR(用于Automation的寬字符)操作。需要說明的是,正確設(shè)置ConnectionString是連接數(shù)據(jù)源的關(guān)鍵。不同的數(shù)據(jù),其連接字串有所不同。HRESULTConnection::Open(_bstr_t

ConnectionString,_bstr_t

UserID,_bstr_t

Password,longOptions)9.4.1_ConnectionPtr9.4.1_RecordsetPtr__RecordsetPtr是一個(gè)記錄集對(duì)象。它對(duì)記錄集提供了更多的控制功能,如記錄鎖定,游標(biāo)控制等。它不一定要使用一個(gè)已經(jīng)創(chuàng)建的數(shù)據(jù)連接,可以用一個(gè)連接串代替連接指針賦給__RecordsetPtr的connection成員變量,讓它自己創(chuàng)建數(shù)據(jù)連接。如果要使用多個(gè)記錄集,最好的方法是使用已經(jīng)創(chuàng)建了數(shù)據(jù)連接的全局_ConnectionPtr接口,然后使用__RecordsetPtr執(zhí)行存儲(chǔ)過程和SQL語句。HRESULTRecordset15::Open(const_variant_t&Source,

const_variant_t&ActiveConnection,

enum

CursorTypeEnum

CursorType,

enum

LockTypeEnum

LockType,

longOptions)讀取數(shù)據(jù):_variant_t

var=m_pRecordset->Fields->GetItem(字段名)->Value

或者:_variant_t

var=m_pRecordset->GetCollect(“Name”)

9.4.1_RecordsetPtr修改記錄:

m_pRecordset->PutCollect("Name",_variant_t(m_Name));移動(dòng)指針:

m_pRecordset->MoveNext();

m_pRecordset->Move()插入記錄:

m_pRecordset->AddNew();

m_pRecordset->PutCollect("Name",_variant_t(m_Name));

m_pRecordset->PutCollect("Age",atol(m_Age));

m_pRecordset->Update();初始化:m_pRecordset->m_pRecordset.CreateInstance(__uuidof(Recordset));[例Ex_ADO]添加對(duì)ADO的支持(1)

創(chuàng)建單文檔應(yīng)用程序Ex_ADO,在第6步將CEx_ADOView的基類由默認(rèn)的CView選擇為CListView類。(2)

在CEx_ADOView::PreCreateWindow函數(shù)添加下列代碼,用來設(shè)置列表視圖內(nèi)嵌列表控件的風(fēng)格:BOOLCEx_ADOView::PreCreateWindow(CREATESTRUCT&cs){

cs.style|=LVS_REPORT;//報(bào)表風(fēng)格

returnCListView::PreCreateWindow(cs);}(3)在stdafx.h文件中添加對(duì)ADO支持的代碼:#endif//_AFX_NO_AFXCMN_SUPPORT#include<afxcmn.h>//MFCsupportforWindowsCommonControls#import"C:\ProgramFiles\CommonFiles\System\ADO\msado15.dll"\no_namespacerename("EOF","adoEOF")#include<icrsint.h>//{{AFX_INSERT_LOCATION}}

預(yù)編譯命令#import是編譯器將此命令中所指定的動(dòng)態(tài)鏈接庫文件引入到程序中,并從動(dòng)態(tài)鏈接庫文件中抽取出其中的對(duì)象和類的信息。

icrsint.h文件包含了VisualC++擴(kuò)展的一些預(yù)處理指令、宏等的定義,用于與數(shù)據(jù)庫數(shù)據(jù)綁定。(4)CEx_ADOApp::InitInstance添加代碼,用來對(duì)ADO的

COM環(huán)境進(jìn)行初始化BOOLCEx_ADOApp::InitInstance(){::CoInitialize(NULL);

AfxEnableControlContainer(); …}(5)在Ex_ADOView.h文件中為CEx_ADOView定義三個(gè)ADO對(duì)象指針變量:public:_ConnectionPtr

m_pConnection;_RecordsetPtr

m_pRecordset;_CommandPtr

m_pCommand;_ConnectionPtr、_RecordsetPtr和_CommandPtr分別是ADO對(duì)象Connection、Recordset和Command的智能指針類型。2.連接數(shù)據(jù)源

ADO使用Connection對(duì)象來建立與數(shù)據(jù)庫服務(wù)器的連接,它相當(dāng)于MFC的CDatabase類。和CDatabase類一樣,調(diào)用Connection對(duì)象的Open即可建立與服務(wù)器的連接。HRESULTConnection::Open(_bstr_t

ConnectionString,_bstr_t

UserID,_bstr_t

Password,longOptions)voidCEx_ADOView::OnDestroy(){ CListView::OnDestroy(); if(m_pConnection)m_pConnection->Close();//關(guān)閉連接 }3.關(guān)閉連接

CEx_ADOView映射WM_DESTROY消息,并添加下列代碼:4.獲取數(shù)據(jù)源信息Connection對(duì)象除了建立與數(shù)據(jù)庫服務(wù)器的連接外,還可以通過OpenSchema來獲取數(shù)據(jù)源的自有信息。下面的代碼用來獲取student.mdb的數(shù)據(jù)表名和字段名,并將內(nèi)容顯示在列表視圖中:voidCEx_ADOView::OnInitialUpdate(){

CListView::OnInitialUpdate();//初始化Connection指針

m_pConnection.CreateInstance(__uuidof(Connection));//初始化Recordset指針

m_pRecordset.CreateInstance(__uuidof(Recordset));//初始化Recordset指針

m_pCommand.CreateInstance(__uuidof(Command));

//連接數(shù)據(jù)源為"DatabaseExampleForVC++"

m_pConnection->ConnectionString="DSN=DatabaseExampleForVC++";

//允許連接超時(shí)時(shí)間,單位為秒

m_pConnection->ConnectionTimeout=30;HRESULThr=m_pConnection->Open("","","",0);//獲取數(shù)據(jù)表名和字段名

if(hr!=S_OK)

MessageBox(“無法連接指定的數(shù)據(jù)庫!”);_RecordsetPtr

pRstSchema=NULL; //定義一個(gè)記錄集指針

//獲取表信息

pRstSchema=m_pConnection->OpenSchema(adSchemaColumns);//將表信息顯示在列表視圖控件中

CListCtrl&m_ListCtrl=GetListCtrl();

CStringstrHeader[3]={"序號(hào)","TABLE_NAME","COLUMN_NAME"};for(inti=0;i<3;i++)

m_ListCtrl.InsertColumn(i,strHeader[i],LVCFMT_LEFT,120);

int

nItem=0;

CString

str;_bstr_t

value;

while(!(pRstSchema->adoEOF)){str.Format("%d",nItem+1);

m_ListCtrl.InsertItem(nItem,str); for(inti=1;i<3;i++){value=pRstSchema->Fields->GetItem((_bstr_t)(LPCSTR)strHeader[i])->Value;

m_ListCtrl.SetIt

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論