版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第8章
數(shù)據(jù)庫(kù)編程
(DatabaseProgramming)主講教師:劉懷廣
lhg81219@163.comVisualC++6.0為用戶提供了ODBC(開(kāi)放數(shù)據(jù)庫(kù)連接)
、DAO(數(shù)據(jù)訪問(wèn)對(duì)象)及OLEDB(OLE數(shù)據(jù)庫(kù))三種數(shù)據(jù)庫(kù)方式。這三種方式中最簡(jiǎn)單也最常用的是ODBC,因此本章先來(lái)重點(diǎn)介紹MFC的ODBC編程方法和技巧,然后介紹基于OLEDB的ADO(ActiveXDataObjects,ActiveX數(shù)據(jù)對(duì)象)技術(shù),最后介紹一些用于數(shù)據(jù)庫(kù)的ActiveX控件。數(shù)據(jù)庫(kù)概述8.1MFCODBC數(shù)據(jù)庫(kù)概述ODBC是一種使用SQL的程序設(shè)計(jì)接口,使用ODBC能使用戶編寫(xiě)數(shù)據(jù)庫(kù)應(yīng)用程序變得容易簡(jiǎn)單,避免了與數(shù)據(jù)源相連接的復(fù)雜性。MFC的ODBC數(shù)據(jù)庫(kù)類CDatabase(數(shù)據(jù)庫(kù)類)、CRecordSet(記錄集類)和CRecordView(記錄視圖類)可為用戶管理數(shù)據(jù)庫(kù)提供了切實(shí)可行的解決方案。8.1.1數(shù)據(jù)庫(kù)基本概念1.數(shù)據(jù)庫(kù)和數(shù)據(jù)庫(kù)管理系統(tǒng)DBMS
數(shù)據(jù)庫(kù)是指以一定的組織形式存放在計(jì)算機(jī)存儲(chǔ)介質(zhì)上的相互關(guān)聯(lián)的數(shù)據(jù)的集合。DBMS:包括數(shù)據(jù)庫(kù)的建立和記錄的輸入、修改、檢索、顯示、刪除和統(tǒng)計(jì)等。流行的DBMS都提供了一個(gè)SQL接口。8.1.1數(shù)據(jù)庫(kù)基本概念2.SQL
DBMS中訪問(wèn)和操作的語(yǔ)言,SQL(結(jié)構(gòu)化查詢語(yǔ)言)語(yǔ)句分為兩類:
DDL(DataDefinitionLanguage,數(shù)據(jù)定義語(yǔ)言)語(yǔ)句,它是用來(lái)創(chuàng)建表、索引等;
DML(DataManipulationLanguage,數(shù)據(jù)操作語(yǔ)言)語(yǔ)句,這些語(yǔ)句是用來(lái)讀取數(shù)據(jù)、更新數(shù)據(jù)和執(zhí)行其他類似操作的語(yǔ)句。3.ODBC、DAO和OLEDB
ODBC提供了應(yīng)用程序接口(API),使得任何一個(gè)數(shù)據(jù)庫(kù)都可以通過(guò)ODBC驅(qū)動(dòng)器與指定的DBMS相聯(lián)。
DAO使用Jet數(shù)據(jù)庫(kù)引擎形成一系列的數(shù)據(jù)訪問(wèn)對(duì)象:數(shù)據(jù)庫(kù)對(duì)象、表和查詢對(duì)象、記錄集對(duì)象等。
OLEDB提供一個(gè)統(tǒng)一的數(shù)據(jù)訪問(wèn)接口,使得應(yīng)用程序可以使用同樣的方法訪問(wèn)各種數(shù)據(jù),而不用考慮數(shù)據(jù)的具體存儲(chǔ)地點(diǎn)、格式或類型。8.1.1數(shù)據(jù)庫(kù)基本概念4.ADO(ActiveXDataObjects)
ADO是目前比較流行的客戶端數(shù)據(jù)庫(kù)編程技術(shù)。ADO技術(shù)基于COM(ComponentObjectModel,組件對(duì)象模型),是遠(yuǎn)程數(shù)據(jù)存取的發(fā)展方向。8.1.1數(shù)據(jù)庫(kù)基本概念8.1.2MFCODBC向?qū)н^(guò)程用MFCAppWizard使用ODBC數(shù)據(jù)庫(kù)的一般過(guò)程是:①用Access或其他數(shù)據(jù)庫(kù)工具構(gòu)造一個(gè)數(shù)據(jù)庫(kù);②在Windows中為剛才構(gòu)造的數(shù)據(jù)庫(kù)定義一個(gè)ODBC數(shù)據(jù)源;③在創(chuàng)建數(shù)據(jù)庫(kù)處理的文檔應(yīng)用程序向?qū)е羞x擇數(shù)據(jù)源;④設(shè)計(jì)界面,并使控件與數(shù)據(jù)表字段關(guān)聯(lián)。1.構(gòu)造數(shù)據(jù)庫(kù)
數(shù)據(jù)庫(kù)表與表之間的關(guān)系構(gòu)成了一個(gè)數(shù)據(jù)庫(kù)。作為示例,這里用MicrosoftAccess創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)Student.mdb,其中暫包含一個(gè)數(shù)據(jù)表score,用來(lái)描述學(xué)生課程成績(jī)。在表中包括上、下兩部分,上部分是數(shù)據(jù)表的記錄內(nèi)容,下部分是數(shù)據(jù)表的結(jié)構(gòu)內(nèi)容。
表8.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”頁(yè)面是用來(lái)定義用戶自己在本地計(jì)算機(jī)使用的數(shù)據(jù)源名(DSN),如圖8.2所示。圖8.3“創(chuàng)建新數(shù)據(jù)源”對(duì)話框
圖8.4ODBCAccess安裝對(duì)話框
創(chuàng)建用戶DSN的過(guò)程如下:(1)單擊[添加]→彈出“創(chuàng)建新數(shù)據(jù)源”→選擇“MicrosoftAccessDriver”。(2)單擊[完成]→進(jìn)入指定驅(qū)動(dòng)程序的安裝對(duì)話框→單擊[選擇]將前面創(chuàng)建的數(shù)據(jù)庫(kù)調(diào)入→在數(shù)據(jù)源名輸入“DatabaseExampleForVC++”,結(jié)果如圖8.4所示。(3)單擊[確定]按鈕,剛才創(chuàng)建的用戶數(shù)據(jù)源被添加在“ODBC數(shù)據(jù)源管理器”的“用戶數(shù)據(jù)源”列表中。如圖8.5所示。圖8.5用戶數(shù)據(jù)源列表8.1.2MFCODBC向?qū)н^(guò)程8.1.2MFCODBC向?qū)н^(guò)程表8.2MFC支持?jǐn)?shù)據(jù)庫(kù)的不同選項(xiàng)3.在MFCAppWizard中選擇數(shù)據(jù)源1)創(chuàng)建一個(gè)支持?jǐn)?shù)據(jù)庫(kù)的文檔應(yīng)用程序Ex_ODBC。2)在向?qū)У牡?步對(duì)話框中加入數(shù)據(jù)庫(kù)的支持。其中各選項(xiàng)的含義如表8.2所示。3)選中“數(shù)據(jù)庫(kù)查看使用文件支持”項(xiàng),單擊[DataSource]按鈕,彈出“DatabaseOptions”對(duì)話框,從中選擇ODBC的數(shù)據(jù)源“DatabaseExampleForVC++”,如圖8.7所示。圖8.7“DatabaseOptions”對(duì)話框
8.1.2MFCODBC向?qū)н^(guò)程(4)保留其他默認(rèn)選項(xiàng),單擊[OK]按鈕,彈出“SelectDatabaseTables”對(duì)話框,從中選擇要使用的表score。(5)單擊[OK]按鈕,又回到了向?qū)У牡?步對(duì)話框。(6)單擊[完成]按鈕。開(kāi)發(fā)環(huán)境自動(dòng)打開(kāi)表單視圖CEx_ODBCView的對(duì)話框資源模板IDD_EX_ODBC_FORM以及相應(yīng)的對(duì)話框編輯器。(7)編譯并運(yùn)行,結(jié)果如圖8.9所示。記錄瀏覽按鈕圖8.9Ex_ODBC運(yùn)行結(jié)果8.1.2MFCODBC向?qū)н^(guò)程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ì)話框資源模板添加控件。8.1.2MFCODBC向?qū)н^(guò)程表8.3表單對(duì)話框控件及屬性(2)按快捷鍵Ctrl+W→切換到MemberVariables頁(yè)面→為上述控件添加相關(guān)聯(lián)的數(shù)據(jù)成員。與以往添加控件變量不同的是,這里添加的控件變量都是由系統(tǒng)自動(dòng)定義的,并與數(shù)據(jù)庫(kù)表字段相關(guān)聯(lián)的。8.1.2MFCODBC向?qū)н^(guò)程表8.4控件變量(3)按照上一步驟的方法,為表8.4所示的其他控件依次添加相關(guān)聯(lián)的成員變量。需要說(shuō)明的是,控件變量的范圍和大小應(yīng)與數(shù)據(jù)表中的字段一一對(duì)應(yīng)。(4)編譯運(yùn)行并測(cè)試。8.1.2MFCODBC向?qū)н^(guò)程8.1.3ODBC數(shù)據(jù)表綁定更新圖8.14“MFCClassWizard”(1)按快捷鍵Ctrl+W,切換到“MemberVariables”頁(yè)面。(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”,選擇要使用的表。8.1.3ODBC數(shù)據(jù)表綁定更新(5)單擊[OK],又回到MFCClassWizard界面。(6)單擊[BindAll]按鈕,MFCWizard將自動(dòng)為字段落添加相關(guān)聯(lián)的變量。8.1.3ODBC數(shù)據(jù)表綁定更新8.2MFCODBC應(yīng)用編程
使用MFC所供的ODBC類:CDatabase(數(shù)據(jù)庫(kù)類)、CRecordSet(記錄集類)和CRecordView(可視記錄集類)。
CDatabase類:提供對(duì)數(shù)據(jù)源的連接,通過(guò)它可以對(duì)數(shù)據(jù)源進(jìn)行操作;
CRecordSet類:為用戶提供了對(duì)表記錄進(jìn)行操作的許多功能,如查詢記錄、添加記錄、刪除記錄、修改記錄等。
CRecordView類:控制并顯示數(shù)據(jù)庫(kù)記錄,該視圖是直接連到一個(gè)CRecordSet對(duì)象的表單視圖。8.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)行查詢,并將查找到的記錄顯示在前面添加的控件中。具體過(guò)程如下:(1)打開(kāi)Ex_ODBC應(yīng)用程序的表單資源,按圖8.18所示的布局:添加編輯框ID為IDC_EDIT_QUERY,“查詢”按鈕ID為IDC_BUTTON_QUERY。8.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();//如果記錄集打開(kāi),則先關(guān)閉
m_pSet->m_strFilter.Format("studentno='%s'",m_strQuery);
//studentno是score表的字段名,用來(lái)指定查詢條件
m_pSet->m_strSort="course";
//course是score表的字段名,用來(lái)按course字段從小到大排序
m_pSet->Open();//打開(kāi)記錄集
if(!m_pSet->IsEOF())//如果打開(kāi)記錄集有記錄
UpdateData(FALSE);//自動(dòng)更新表單中控件顯示的內(nèi)容
else MessageBox("沒(méi)有查到你要找的學(xué)號(hào)記錄!");}m_strFilter和m_strSort是CRecordSet的成員變量,用來(lái)執(zhí)行條件查詢和結(jié)果排序。其中,m_strFilter稱為“過(guò)濾字符串”,相當(dāng)于SQL語(yǔ)句中WHERE后的條件串;而m_strSort稱為“排序字符串”,相當(dāng)于SQL語(yǔ)句中ORDERBY后的字符串。若字段的數(shù)據(jù)類型是文本,則需要在m_strFilter字符串中將單引號(hào)將查詢的內(nèi)容括起來(lái),對(duì)于數(shù)字,則不需要用單引號(hào)。8.2.1查詢記錄8.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ù)庫(kù)m_pSet->Requery(); //刷新記錄集,這在快照集方式下是必須的CRecordSet類為用戶提供了成員函數(shù)用來(lái)添加記錄、刪除記錄和修改記錄等。1.增加記錄使用AddNew函數(shù),但要求數(shù)據(jù)庫(kù)必須是以“可增加”的方式打開(kāi)的。8.2.2編輯記錄2.刪除記錄直接使用CRecordSet::Delete刪除記錄。要使操作有效,還需要移動(dòng)記錄函數(shù)CRecordsetStatusstatus;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è)記錄elsem_pSet->MoveFirst(); //移動(dòng)到第一個(gè)記錄處UpdateData(FALSE);3.修改記錄函數(shù)CRecordSet::Edit可以用來(lái)修改記錄,例如:m_pSet->Edit(); //修改當(dāng)前記錄m_pSet->m_name=“杰克遜"; //修改當(dāng)前記錄字段值......m_pSet->Update(); //將修改結(jié)果存入數(shù)據(jù)庫(kù)m_pSet->Requery();8.2.2編輯記錄4.撤消操作如果用戶在進(jìn)行增加或者修改記錄后,希望放棄當(dāng)前操作,則在調(diào)用CRecordSet::Update()函數(shù)之前調(diào)用CRecordSet::Move(AFX_MOVE_REFRESH)來(lái)撤消操作,便可恢復(fù)在增加或修改操作之前的當(dāng)前記錄。8.2.2編輯記錄8.2.3字段操作CRecordSet類中的成員變量m_nFields
:用于保存數(shù)據(jù)表的字段個(gè)數(shù)。成員函數(shù)GetODBCFieldInfo及GetFieldValue可以簡(jiǎn)化多字段的訪問(wèn)操作。voidGetODBCFieldInfo(shortnIndex,CODBCFieldInfo&fieldinfo);nIndex:指定字段索引號(hào),0表示第一個(gè)字段,1表示第二個(gè)字段,以此類推。
fieldinfo是CODBCFieldInfo結(jié)構(gòu)參數(shù),用來(lái)表示字段信息。8.2.3字段操作structCODBCFieldInfo{CStringm_strName; //字段名
SWORDm_nSQLType;//字段的SQL數(shù)據(jù)類型
UDWORDm_nPrecision;//字段的文本大小或數(shù)據(jù)大小
SWORDm_nScale; //字段的小數(shù)點(diǎn)位數(shù)
SWORDm_nNullability;//字段接受空值(NULL)能力};8.2.3字段操作structCRecordsetStatus{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)前記錄的索引表8.5課程信息表(course)及其表結(jié)構(gòu)[例Ex_Field]字段的編程操作1.為Student.mdb添加一個(gè)數(shù)據(jù)表course:用MicrosoftAccess為數(shù)據(jù)庫(kù)Student.mdb添加一個(gè)數(shù)據(jù)表course,如表8.5所示。表中上部分是數(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頁(yè)面,展開(kāi)HeaderFiles所有項(xiàng),雙擊stdafx.h,打開(kāi)該文件。(3)在stdafx.h中添加ODBC數(shù)據(jù)庫(kù)支持的頭文件包含#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)嵌在列表視圖中的列表控件
CCourseSetcSet;
cSet.Open(); //打開(kāi)記錄集
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)
intnItem=0; CStringstr; 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é)果如圖8.24所示。圖8.24Ex_Field第一次運(yùn)行結(jié)果4.在狀態(tài)欄中顯示當(dāng)前記錄號(hào)和記錄總數(shù)(1)在MainFrm.cpp文件中,向原來(lái)的indicators數(shù)組添加一個(gè)元素,用來(lái)在狀態(tài)欄上增加一個(gè)窗格:staticUINTindicators[]={ID_SEPARATOR,//第一個(gè)信息行窗格
ID_SEPARATOR,//第二個(gè)信息行窗格
ID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,};voidDispRecNum(CCourseSet*pSet){ CStringstr; CMainFrame*pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;//獲得主框架窗口的指針
CStatusBar*pStatus=&pFrame->m_wndStatusBar;//獲得主框架窗口中的狀態(tài)欄指針
if(pStatus){ CRecordsetStatusrStatus; 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(){…CStringstr;while(!cSet.IsEOF()) {… }::DispRecNum(&cSet);cSet.Close(); //關(guān)閉記錄集}(4)在Ex_ODBCView.cpp文件的開(kāi)始處增加下列語(yǔ)句:
#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é)果8.2.4多表處理圖8.26Ex_Student運(yùn)行結(jié)果
下面的示例在一個(gè)對(duì)話框中用兩個(gè)控件來(lái)進(jìn)行學(xué)生課程成績(jī)信息的相關(guān)操作,如圖8.26所示,左邊是樹(shù)視圖,用來(lái)顯示學(xué)生成績(jī)、專業(yè)和班級(jí)號(hào)三個(gè)層次信息,單擊班級(jí)號(hào),所有該班級(jí)的學(xué)生課程成績(jī)信息將在右邊的列表視圖中顯示出來(lái)。[例Ex_Student]多表處理1.為數(shù)據(jù)庫(kù)Student.mdb添加一個(gè)數(shù)據(jù)表student用MicrosoftAccess為數(shù)據(jù)庫(kù)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è)樹(shù)控件,在其屬性對(duì)話框中,選中“有按鈕”、“有行(Lines,線)”、“Linesatroot”和“總是顯示選擇”屬性。(5)添加一個(gè)列表控件,在其屬性對(duì)話框中,將“查看”屬性選為“Report”。(6)用MFCClassWizard在CEx_StudentDlg類中,添加樹(shù)控件的控件變量為m_treeCtrl,添加列表控件的控件變量為m_listCtrl。3.添加對(duì)MFCODBC的支持及記錄集在stdafx.h文件中添加ODBC數(shù)據(jù)庫(kù)支持的頭文件包含
#include<afxdb.h>
用MFCClassWizard為數(shù)據(jù)表student、course和score分別創(chuàng)建CRecordSet派生類CStudentSet、CCourseSet和CScoreSet。4.完善左邊樹(shù)控件的代碼(1)為CEx_StudentDlg類添加一個(gè)成員函數(shù)FindTreeItem,用來(lái)查找指定節(jié)點(diǎn)下是否有指定節(jié)點(diǎn)文本的子節(jié)點(diǎn),該函數(shù)的代碼如下:HTREEITEMCEx_StudentDlg::FindTreeItem(HTREEITEMhParent,CStringstr){HTREEITEMhNext;CStringstrItem;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);//獲取打開(kāi)文件夾圖標(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); CStudentSetsSet; sSet.m_strSort=“special”; //按專業(yè)排序
sSet.Open(); while(!sSet.IsEOF()){ hSpec=FindTreeItem(hRoot,sSet.m_special);//查找是否有重復(fù)的專業(yè)節(jié)點(diǎn)
if(hSpec==NULL)//若沒(méi)有重復(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)//若沒(méi)有重復(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è)置列表頭
CStringstrHeader[]={"學(xué)號(hào)","姓名","課程號(hào)","課程所屬專業(yè)", "課程名稱","課程類別","開(kāi)課學(xué)期","課時(shí)數(shù)","學(xué)分","成績(jī)"};intnLong[]={80,80,80,180,180,80,80,80,80,80};for(intnCol=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,用來(lái)根據(jù)指定的條件在列表控件中用報(bào)表形式顯示學(xué)生成績(jī)的所有信息。voidCEx_StudentDlg::DispScoreAndCourseInfo(CStringstrFilter){ m_listCtrl.DeleteAllItems();//刪除所有的列表項(xiàng)
CScoreSetsSet; sSet.m_strFilter=strFilter;//設(shè)置過(guò)濾條件
sSet.Open(); //打開(kāi)score表
intnItem=0; CStringstr; while(!sSet.IsEOF()) {m_listCtrl.InsertItem(nItem,sSet.m_studentno);//插入學(xué)號(hào)
//根據(jù)score表中的studentno(學(xué)號(hào))獲取student表中的"姓名" CStudentSetuSet; 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表中的課程信息
CCourseSetcSet; 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)沒(méi)有子節(jié)點(diǎn),那說(shuō)明該節(jié)點(diǎn)是班級(jí)號(hào)節(jié)點(diǎn)
if(m_treeCtrl.GetChildItem(hSelItem)==NULL){ CStringstrSelItem,str; strSelItem=m_treeCtrl.GetItemText(hSelItem); str.Format("studentnoLIKE'%s%%'",strSelItem.Left(6));
DispScoreAndCourseInfo(str); } *pResult=0;}6.完善兩控件的關(guān)聯(lián)代碼從上圖中可以看出,學(xué)生成績(jī)還沒(méi)有顯示出來(lái),下面將實(shí)現(xiàn)單擊左邊的班級(jí)號(hào),在右邊視圖中顯示該班級(jí)的所有學(xué)生成績(jī)信息。(1)CEx_StudentDlg類添加TVN_SELCHANGED消息處理:
代碼中,調(diào)用DispScoreAndCourseInfo
函數(shù)的參數(shù)是用來(lái)設(shè)置數(shù)據(jù)表(記錄集)打開(kāi)的過(guò)濾條件。str是類似內(nèi)容:“studentnoLIKE210101%”,它使得所有學(xué)號(hào)前面是210101的記錄被打開(kāi)。%是SQL使用的通配符,由于%也是VisaulC++格式前導(dǎo)符,因?yàn)樵诖a中需要兩個(gè)%。(2)編譯運(yùn)行并測(cè)試。8.3ADO數(shù)據(jù)庫(kù)編程ADO最主要的優(yōu)點(diǎn):易于使用、速度快、內(nèi)存開(kāi)銷小,它使用最少的網(wǎng)絡(luò)流量,并且在前端和數(shù)據(jù)源之間使用最少的層數(shù),它是一個(gè)輕量、高性能的接口。ADO實(shí)際上就是由一組Automation對(duì)象構(gòu)成的組件,因此可以像使用其它任何Automation對(duì)象一樣使用ADO。ADO中最重要的對(duì)象有三個(gè):Connection、Command和Recordset,它們分別表示“連接”對(duì)象、“命令”對(duì)象和“記錄集”對(duì)象。8.3.1ADO編程的一般過(guò)程在MFC應(yīng)用程序中使用ADO數(shù)據(jù)庫(kù)的一般過(guò)程是:①添加對(duì)ADO的支持;②創(chuàng)建一個(gè)數(shù)據(jù)源連接;③對(duì)數(shù)據(jù)源中的數(shù)據(jù)庫(kù)進(jìn)行操作;④關(guān)閉數(shù)據(jù)源。1.添加對(duì)ADO的支持
ADO編程有三種方式:使用預(yù)處理指令#import、使用MFC中的CIDispatchDriver和直接使用COM提供的API。這三種方式中,第一種最為簡(jiǎn)便,故這里采有用這種方法。下面以一個(gè)示例過(guò)程來(lái)說(shuō)明在MFC應(yīng)用程序中添加對(duì)ADO的支持。[例Ex_ADO]添加對(duì)ADO的支持(1)
創(chuàng)建單文檔應(yīng)用程序Ex_ADO,在第6步將CEx_ADOView的基類由默認(rèn)的CView選擇為CListView類。(2)
在CEx_ADOView::PreCreateWindow函數(shù)添加下列代碼,用來(lái)設(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)鏈接庫(kù)文件引入到程序中,并從動(dòng)態(tài)鏈接庫(kù)文件中抽取出其中的對(duì)象和類的信息。
icrsint.h文件包含了VisualC++擴(kuò)展的一些預(yù)處理指令、宏等的定義,用于與數(shù)據(jù)庫(kù)數(shù)據(jù)綁定。(4)CEx_ADOApp::InitInstance添加代碼,用來(lái)對(duì)ADO的
COM環(huán)境進(jìn)行初始化BOOLCEx_ADOApp::InitInstance(){::CoInitialize(NULL);AfxEnableControlContainer(); …}(5)在Ex_ADOView.h文件中為CEx_ADOView定義三個(gè)ADO對(duì)象指針變量:public:_ConnectionPtrm_pConnection;_RecordsetPtrm_pRecordset;_CommandPtrm_pCommand;_ConnectionPtr、_RecordsetPtr和_CommandPtr分別是ADO對(duì)象Connection、Recordset和Command的智能指針類型。2.連接數(shù)據(jù)源
ADO使用Connection對(duì)象來(lái)建立與數(shù)據(jù)庫(kù)服務(wù)器的連接,它相當(dāng)于MFC的CDatabase類。和CDatabase類一樣,調(diào)用Connection對(duì)象的Open即可建立與服務(wù)器的連接。ConnectionString:連接字串,UserID:用戶名,Password:登錄密碼,Options是選項(xiàng),通常用于設(shè)置同步和異步等方式。_bstr_t是一個(gè)COM類,用于字符串BSTR(用于Automation的寬字符)操作。需要說(shuō)明的是,正確設(shè)置ConnectionString是連接數(shù)據(jù)源的關(guān)鍵。不同的數(shù)據(jù),其連接字串有所不同,見(jiàn)表8.7所示。HRESULTConnection::Open(_bstr_t
ConnectionString,_bstr_tUserID,_bstr_tPassword,longOptions)表8.7Connection對(duì)象的連接字串格式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ù)庫(kù)服務(wù)器的連接外,還可以通過(guò)OpenSchema來(lái)獲取數(shù)據(jù)源的自有信息。下面的代碼用來(lái)獲取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(“無(wú)法連接指定的數(shù)據(jù)庫(kù)!”);_RecordsetPtrpRstSchema=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);intnItem=0;CStringstr;_bstr_tvalue; 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.SetItemText(nItem,i,value); } pRstSchema->MoveNext(); nItem++; } pRstSchema->Close();}__uuidof:獲取對(duì)象的的全局唯一標(biāo)識(shí)(GUID)。ConnectionTimeout:連接超時(shí)屬性,單位為秒。OpenSchema方法中的adSchemaColumns是一個(gè)預(yù)定義的枚舉常量,用來(lái)獲取與“列”(字段)相關(guān)的信息記錄集。該信息記錄集的主要字段名有“TABLE_NAME”、“COLUMN_NAME”;類似的,若在OpenSchema方法中指定adSchemaTables枚舉常量,則返回的記錄集的字段名主要有“TABLE_NAME”、“TABLE_TYPE”。8.3.2Recordset對(duì)象使用Recordset:從數(shù)據(jù)表或某一個(gè)SQL執(zhí)行后獲得記錄集,通過(guò)Recordset對(duì)象的AddNew、Update和Delete方法可實(shí)現(xiàn)記錄的添加、修改和刪除操作。1.讀取數(shù)據(jù)表全部記錄內(nèi)容(1)打開(kāi)IDR_MAINFRAME,在頂層菜單“查看”下添加一個(gè)“顯示Course表記錄”子菜單,將其ID號(hào)設(shè)為D_VIEW_COURSE。(2)按快捷鍵Ctrl+W,向CEx_ADOView類添加ID_VIEW_COURSE的COMMAND消息映射,保留默認(rèn)的映射函數(shù)OnViewCourse:voidCEx_ADOView::OnViewCourse(){ CListCtrl&m_ListCtrl=GetListCtrl();
//刪除列表中所有行和列表頭
m_ListCtrl.DeleteAllItems(); intnColumnCount=m_ListCtrl.GetHeaderCtrl()->GetItemCount(); for(inti=0;i<nColumnCount;i++) m_ListCtrl.DeleteColumn(0); m_pRecordset->Open("Course",//指定要打開(kāi)的表
m_pConnection.GetInterfacePtr(),//獲取當(dāng)前數(shù)據(jù)庫(kù)連接的接口指針
adOpenDynamic, //動(dòng)態(tài)游標(biāo)類型,可以使用Move等操作
adLockOptimistic,adCmdTable);//建立列表控件的列表頭
FieldsPtrflds=m_pRecordset->GetFields();//獲取當(dāng)前表的字段指針
_variant_tIndex;Index.vt=VT_I2; m_ListCtrl.InsertColumn(0,"序號(hào)",LVCFMT_LEFT,60); for(i=0;i<(int)flds->GetCount();i++){ Index.iVal=i; m_ListCtrl.InsertColumn(i+1,(LPSTR)flds->GetItem(Index)->GetName(),LVCFMT_LEFT,140); }
//顯示記錄
_bstr_tstr,value; intnItem=0; CStringstrItem; while(!m_pRecordset->adoEOF){strItem.Format("%d",nItem+1); m_ListCtrl.InsertItem(nItem,strItem); for(i=0;i<(int)flds->GetCount();i++){ Index.iVal=i; str=flds->GetItem(Index)->GetName(); value=m_pRecordset->GetCollect(str); m_ListCtrl.SetItemText(nItem,i+1,(LPCSTR)value); } m_pRecordset->MoveNext(); nItem++; } m_pRecordset->Close(); }_variant_t:一個(gè)用于COM的VARIANT類,VARIANT類型是一個(gè)C結(jié)構(gòu),由于它既包含了數(shù)據(jù)本身,也包含了數(shù)據(jù)的類型,它可以實(shí)現(xiàn)各種不同的自動(dòng)化數(shù)據(jù)的傳輸。(3)編譯運(yùn)行并測(cè)試,結(jié)果如圖8.30所示。圖8.30顯示Course表所有記錄8.3.2Recordset對(duì)象使用2.添加、修改和刪除記錄向course表中新添加一個(gè)記錄可有下列代碼://打開(kāi)記錄集m_pRecordset->AddNew();//添加新記錄m_pRecordset->PutCollect("courseno",_variant_t("2112111"));m_pRecordset->PutCollect("coursehourse",_variant_t(60));…m_pRecordset->Update();//使添加有效//關(guān)閉記錄集若從course表中刪除一個(gè)記錄可有下列代碼://打開(kāi)記錄集……m_pRecordset->Delete(adAffectCurrent);//刪除當(dāng)前行m_pRecordset->MoveFirst();//調(diào)用Move方法,使刪除有效
//關(guān)閉記錄集若從course表中修改一個(gè)記錄可有下列代碼://打開(kāi)記錄集m_pRecordset->PutCollect("courseno",_variant_t("2112111"));m_pRecordset->PutCollect("coursehourse",_variant_t(60));…m_pRecordset->Update();//使修改有效
//關(guān)閉記錄集
特別強(qiáng)調(diào)的是,數(shù)據(jù)庫(kù)的表名不能與ADO的某些關(guān)鍵字串同名,例如:user等。另外,通常用Command對(duì)象執(zhí)行SQL命令來(lái)實(shí)現(xiàn)數(shù)據(jù)表記錄的查詢、添加、更新和刪除等操作,而用Recordset對(duì)象獲取記錄集,用來(lái)顯示記錄內(nèi)容。8.3.3Command對(duì)象使用Command對(duì)象用來(lái)執(zhí)行SQL命令。下面簡(jiǎn)單介紹SQL幾個(gè)常用語(yǔ)句:1.SELECT語(yǔ)句一個(gè)典型的SQL查詢可以從指定的數(shù)據(jù)庫(kù)表中“選擇”信息,這時(shí)就需要使用SELECT語(yǔ)句來(lái)執(zhí)行。SELECT語(yǔ)句格式如下:
SELECT字段名
FROM表名[WHERE子句][ORDERBY子句]…
它的最簡(jiǎn)單形式是:
SELECT*FROMtableName
其中,星號(hào)(*)用來(lái)指定從數(shù)據(jù)庫(kù)的tableName表中選擇所有的字段(列)。若要從表中選擇指定字段的記錄,則將星號(hào)(*)用字段列表來(lái)代替,多個(gè)字段之間用逗號(hào)分隔。(1)WHERE子句SELECTcolumn1,
column2,…FROMtableNameWHEREconditionWHERE子句中的條件可以<(小于)、>(大于)、<=(小于等于)、>=(大于等于)、=(等于)、<>(不等于)和LIKE等運(yùn)算符。其中,LIKE用于匹配條件的查詢,它可以使用“%”和“_(下劃線)”等通配符,“%”表示可以出現(xiàn)0個(gè)或多個(gè)字符,“_”表示該位置處只能出現(xiàn)1個(gè)字符。(1)SELECT*FROMScoreWHEREstudentnoLIKE‘21%’則將Score表中所有學(xué)號(hào)以21打頭的記錄查詢出來(lái)。注意,LIKE后面的字符串是以單引號(hào)來(lái)標(biāo)識(shí)。(2)SELECT*FROMScoreWHEREstudentnoLIKE‘210105__’則將Score表中所有學(xué)號(hào)以210105打頭,且學(xué)號(hào)為8位的記錄查詢出來(lái).(3)還可用AND(與)、OR(或)以及NOT(非)運(yùn)算符來(lái)構(gòu)造復(fù)合條件查詢:SELECT*FROMScoreWHEREscore<=80ANDscore>=70ASC:升序(從低到高),DESC:降序(從高到低),col1、col2…分別用來(lái)指定是按什么字段來(lái)排序。當(dāng)指定多個(gè)字段時(shí),則先按col1排序,當(dāng)有相同col1的記錄時(shí),則相同的記錄按col2排序,依此類推。(2)ORDERBY子句SELECTcolumn1,
column2,…FROMtableName[WHEREcondition]ORDERBYcol1,
co2,…ASC|DESC2.INSERT語(yǔ)句INSERTINTO
tableName(col1,col2,col3,…,colN)
VALUES
(val1,val2,val3,…valN)tableName:指定插入新記錄的數(shù)據(jù)表,tableName后跟一對(duì)圓括號(hào),包含一個(gè)以逗號(hào)分隔的列(字段)名的列表,VALUES后面的圓括號(hào)內(nèi)是一個(gè)以逗號(hào)分隔的值列表,它與tableName后面的列名列表是一一對(duì)應(yīng)的。需要說(shuō)明的是,若某個(gè)記錄的某個(gè)字段值是字符串,則需要用單引號(hào)來(lái)括起來(lái)。例如:INSERTINTOStudent(studentno,studentname)VALUES('21010503','張小峰')將在Student中插入一個(gè)新行,其中studentno(學(xué)號(hào))為“21010503”,studentname(學(xué)生姓名)為“張小峰”,對(duì)于該記錄的其它字段值,由于沒(méi)有指定相應(yīng)的值,其結(jié)果由系統(tǒng)決定。3.UPDATE語(yǔ)句UPDATE
tableNameSET
column1=value1,
column2=value2,…,columnN=valueN
WHEREcondition該語(yǔ)句可以更新tableName表中一行記錄或多行記錄的數(shù)據(jù),這取決于WHERE后面的條件。關(guān)鍵字SET后面是以逗號(hào)分隔的“列名/值”列表。例如:UPDATEStudentSETstudentname='王鵬'WHEREstudentno='21010503'將學(xué)號(hào)為“21010503”的記錄中的studentname字段內(nèi)容更新為“王鵬”。4.DELETE語(yǔ)句DELETE語(yǔ)句用來(lái)從表中刪除記錄,其常用形式如下:
DELETEFROMtableNameWHEREcondition
該語(yǔ)句可以刪除tableNam表中一行記錄或多行記錄,這取決于WHERE后面的條件。8.4數(shù)據(jù)庫(kù)相關(guān)的ActiveX控件
在前面的數(shù)據(jù)庫(kù)處理中,一次只能顯示出一行記錄,且修改或添加等操作不能“可視化”地進(jìn)行。為了彌補(bǔ)MFC的這種不足,在VisualC++6.0中允許用戶使用一些ActiveX控件用來(lái)更好地操作數(shù)據(jù)庫(kù),這些控件包括MSFlexGrid、RemoteData、DBGrid等。8.4.1使用MSFlexGrid控件可以顯示網(wǎng)格數(shù)據(jù),也可以對(duì)其進(jìn)行操作。網(wǎng)格中可以包含字符串和圖片。利用MSFlexGrid可以將某個(gè)表的所有記錄顯示。[例Ex_Grid]使用RemoteData和DBGrid控件1.將控件的類添加到項(xiàng)目中(1)創(chuàng)建一個(gè)單文檔應(yīng)用程序Ex_Grid。(2)第2步對(duì)話框中,選中“數(shù)據(jù)庫(kù)查看使用文件支持”,單擊[DataSource],彈出“DatabaseOptions”,從中選擇ODBC的數(shù)據(jù)源“DatabaseExampleForVC++”。保留其他默認(rèn)選項(xiàng),單擊[OK],在彈出的“SelectDatabaseTables”對(duì)話框中,選擇要使用的表score。(3)單擊[OK],又回到了第2步對(duì)話框。單擊[完成]。開(kāi)發(fā)環(huán)境自動(dòng)打開(kāi)表單視圖CEx_GridView的對(duì)話框資源模板IDD_EX_GRID_FORM。(4)在打開(kāi)的表單資源模板中右擊鼠標(biāo),從彈出的快捷菜單中選擇“InsertActiveControl”命令,出現(xiàn)如圖8.31所示“插入Active控件”對(duì)話框。(5)在列表中選擇MicorsoftFlexGridControl控件,單擊[確定]按鈕,該控件就添加到表單資源中,參看圖8.33,調(diào)整其大小和位置。圖8.31“插入ActiveX控件”對(duì)話框圖8.32MSFlexGrid控件的屬性對(duì)話框2.修改MSFlexGrid控件屬性右擊MicorsoftFlexGridControl控件,彈出的菜單中選擇“屬性”或“屬性MSFlexGridObject”命令均可打開(kāi)控件的屬性對(duì)話框,如圖8.32所示。
MSFlexGrid控件的屬性要比VisualC++的控件屬性要多,如“General”、“通用”、“樣式”、“字體”、“顏色”、“圖片”等。這些屬性不僅能設(shè)置控件的字體、顏色,而且能設(shè)置網(wǎng)格的行數(shù)和列數(shù)以及其他的功能。3.編程控制(1)保留默認(rèn)的屬性及其控件標(biāo)識(shí)符IDC_MSFLEXGRID1。(2)用MFCClassWizard在CEx_GridView類中為剛才添加的MSFlexGrid控件設(shè)置一個(gè)相關(guān)聯(lián)的控件變量m_MSFGrid。在此步驟中會(huì)出現(xiàn)一些對(duì)話框,用于詢問(wèn)是否要添加相關(guān)控件的類代碼等,選擇[是]。(3)在CEx_ODBCView類的OnInitialUpdate函數(shù)中添加下列代碼:voidCEx_GridView::OnInitialUpdate(){ … while(!m
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年白城a1客運(yùn)資格證
- 2024年武漢小型客運(yùn)從業(yè)資格證考試題答案
- 2024年南昌客運(yùn)駕駛員考試試卷答案
- 2025屆重慶市萬(wàn)州龍駒中學(xué)生物高一上期末統(tǒng)考模擬試題含解析
- 2024年西寧考取客運(yùn)資格證需要什么條件
- 2024年石嘴山客運(yùn)上崗證模擬考試題
- 浙江省教育綠色評(píng)價(jià)聯(lián)盟2025屆英語(yǔ)高三上期末聯(lián)考模擬試題含解析
- 遼寧省四校聯(lián)考2025屆高三數(shù)學(xué)第一學(xué)期期末學(xué)業(yè)水平測(cè)試試題含解析
- 浙江省溫州市普通高中2025屆高一上數(shù)學(xué)期末調(diào)研模擬試題含解析
- 徐州市2025屆生物高三上期末考試試題含解析
- 《創(chuàng)意改善生活》課件 2024-2025學(xué)年湘美版(2024)初中美術(shù)七年級(jí)上冊(cè)
- 應(yīng)急救援方案
- 2024-2025學(xué)年 浙教版七年級(jí)數(shù)學(xué)上冊(cè)期中(第1-4章)培優(yōu)試卷
- 2024-2030年“一帶一路”背景下ICT行業(yè)經(jīng)營(yíng)狀況及投資潛力分析研究報(bào)告
- 2024年細(xì)胞治療行業(yè)營(yíng)銷策略方案
- 錐顱術(shù)后護(hù)理
- 邯鄲市2025屆高三年級(jí)第一次調(diào)研監(jiān)測(cè)(一調(diào)) 生物試卷(含答案詳解)
- 知識(shí)點(diǎn)填空練習(xí)-2024-2025學(xué)年統(tǒng)編版道德與法治七年級(jí)上冊(cè)
- 拒絕校園欺凌教育主題課件
- DB37T-動(dòng)物疫病鑒別檢測(cè)技術(shù) 第1部分:豬瘟強(qiáng)毒與豬瘟疫苗弱毒
- 2024年省國(guó)資委選聘兼職外部董事人選(高頻重點(diǎn)復(fù)習(xí)提升訓(xùn)練)共500題附帶答案詳解
評(píng)論
0/150
提交評(píng)論