摘要:本文通過(guò)用VC++6.0實(shí)現(xiàn)一個(gè)程序?qū)嵗齺?lái)介紹如何在一個(gè)普通的無(wú)數(shù)據(jù)庫(kù)關(guān)聯(lián)的應(yīng)用程序中添加ODBC應(yīng)用,使應(yīng)用程序能在原有的功能基礎(chǔ)上增加對(duì)數(shù)據(jù)庫(kù)的操作。

  關(guān)鍵字:VC++ 、ODBC、數(shù)據(jù)庫(kù)

  一、 引言

  數(shù)據(jù)庫(kù)屬于最流行的應(yīng)用程序之一,幾乎每個(gè)商業(yè)部門(mén)都使用數(shù)據(jù)庫(kù)來(lái)記錄、管理各種各樣的數(shù)據(jù)。在VC下我們可以在創(chuàng)建工程時(shí)選擇數(shù)據(jù)庫(kù)支持,并選定數(shù)據(jù)源和相關(guān)的表,并選擇CRecordView作為我們這個(gè)程序的基類(lèi),這樣做可以毫不費(fèi)力的將應(yīng)用程序和數(shù)據(jù)庫(kù)建立了關(guān)聯(lián),而幾乎不用編什么代碼,但這樣做的前提是在新建工程時(shí)已明確知道用到哪個(gè)數(shù)據(jù)庫(kù),并且有相關(guān)的數(shù)據(jù)庫(kù)。事實(shí)上我們往往有許多已做好的應(yīng)用程序和類(lèi),其功能除了未和數(shù)據(jù)源建立關(guān)聯(lián)外以基本滿(mǎn)足要求,我們只要在其基礎(chǔ)上添加ODBC接口,使之與數(shù)據(jù)庫(kù)建立關(guān)聯(lián)即可,這樣做避免了與數(shù)據(jù)庫(kù)無(wú)關(guān)部分代碼的重新編寫(xiě)所造成的重復(fù)性操作,大大提高了代碼的重用性和利用率。所以在普通程序上通過(guò)添加ODBC應(yīng)用而與數(shù)據(jù)庫(kù)建立關(guān)聯(lián)的方法是完全行之有效的。

  二、 ODBC技術(shù)

  ODBC(Open Database Conectivity 開(kāi)放式數(shù)據(jù)庫(kù)互聯(lián))技術(shù),作為Microsoft公司對(duì)數(shù)據(jù)庫(kù)進(jìn)行訪問(wèn)的標(biāo)準(zhǔn)應(yīng)用程序接口(API)和Windows開(kāi)放式服務(wù)體系結(jié)構(gòu)OSA的一個(gè)重要組成部分已廣為眾多的Windows程序員所熟悉、認(rèn)可。ODBC的工作依賴(lài)于數(shù)據(jù)庫(kù)制造商提供的驅(qū)動(dòng)程序,使用ODBC API的時(shí)候,Windows的ODBC管理程序,把數(shù)據(jù)庫(kù)訪問(wèn)的請(qǐng)求傳遞給正確的驅(qū)動(dòng)程序,驅(qū)動(dòng)程序再使用SQL語(yǔ)句指示DBMS完成數(shù)據(jù)庫(kù)訪問(wèn)工作,因此,ODBC的存在為我們開(kāi)發(fā)應(yīng)用數(shù)據(jù)庫(kù)程序提供了非常強(qiáng)大的能力和靈活性。

  三、 程序示例

  (一)打開(kāi)Visual C++,在"File"菜單上點(diǎn)選"New…",然后在彈出的"New"對(duì)話框中選定"MFC AppWizard(exe)"類(lèi)的項(xiàng)目,"Project name"為Normal,按下OK鍵,下一Step 1屏幕中選"Single document"單文檔支持,用到后面的選項(xiàng)除在最后一步選擇"CFormView"作為本工程視類(lèi)的基類(lèi)外均為確省值,此時(shí)即可按下Finish鍵,結(jié)果系統(tǒng)將生成一個(gè)新的項(xiàng)目Normal。

  我們就將此工程當(dāng)做原有的工程,接下來(lái)我們便在此工程基礎(chǔ)上對(duì)其添加ODBC應(yīng)用,使該工程能同數(shù)據(jù)源建立關(guān)聯(lián),能對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行操作和管理。

  (二)打開(kāi)"控制面板"上的"ODBC (32bits)",對(duì)數(shù)據(jù)源進(jìn)行注冊(cè)。為了使ODBC能與數(shù)據(jù)庫(kù)一起工作,就必須把數(shù)據(jù)庫(kù)注冊(cè)到ODBC驅(qū)動(dòng)程序管理器,這項(xiàng)工作可以通過(guò)定義一個(gè)DSN或數(shù)據(jù)源名字來(lái)完成。在彈出的"ODBC數(shù)據(jù)源管理器"中選擇"User DSN"屬性頁(yè),點(diǎn)擊"Add…"按鈕。選擇"Microsoft Access Driver(*.mdb)"作為數(shù)據(jù)源的驅(qū)動(dòng)器,點(diǎn)擊"完成"按鈕。在彈出的"ODBC Microsoft Access 97 Setup"對(duì)話框中在"Data Source Name:"欄添入RP97,"Description:"欄只起注釋說(shuō)明的作用,可以不填,然后點(diǎn)擊"Select…"按鈕,選擇所要注冊(cè)的數(shù)據(jù)源,然后點(diǎn)擊"OK"就完成了對(duì)數(shù)據(jù)源的注冊(cè),到這一步,本機(jī)上的任意程序只要通過(guò)ODBC接口和數(shù)據(jù)源名"RP97"就能完成對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)了。

  (三)在VC的"Workspace"活動(dòng)窗口中選擇"FileView"屬性頁(yè),打開(kāi)標(biāo)準(zhǔn)框架頭文件"StdAfx.h",并在最后一個(gè)#include后面添加對(duì)"afxdb.h"的引用:#include

  (四) 在"Workspace"活動(dòng)窗口中選擇"ClassView"屬性頁(yè),在"Normal Classes"上右鍵,選"New Class…",在彈出的"New Class"對(duì)話框的"Base Class"欄選擇"CRecordSet"做為新添加的類(lèi)的基類(lèi),在"Name"欄填寫(xiě)類(lèi)名"CODBCSet",點(diǎn)擊"OK",在隨后彈出的對(duì)話框的"ODBC"欄選擇剛注冊(cè)的"RP97"數(shù)據(jù)源,點(diǎn)擊"OK"后選擇該數(shù)據(jù)庫(kù)的一個(gè)表,點(diǎn)擊"OK"在"ClassView"里就多了一個(gè)以CRecordSet為基類(lèi)的新類(lèi)"CODBCSet"。下面三個(gè)函數(shù)完成了數(shù)據(jù)庫(kù)各級(jí)元素的綁定工作:

CString CODBCSet::GetDefaultConnect()
{
 return _T("ODBC;DSN=RP97");
}

CString CODBCSet::GetDefaultSQL()
{
 return _T("[單據(jù)表]");
}

void CODBCSet::DoFieldExchange(CFieldExchange* pFX)
{
 //{{AFX_FIELD_MAP(CODBCSet)
 pFX->SetFieldType(CFieldExchange::outputColumn);
 RFX_Text(pFX, _T("[單據(jù)ID]"), m_column1);
 RFX_Text(pFX, _T("[單據(jù)名稱(chēng)]"), m_column2);
 RFX_Text(pFX, _T("[報(bào)帳人]"), m_column3);
 //}}AFX_FIELD_MAP
}

  (五)按同樣的方法再添加一個(gè)基于"generic CWnd"的新類(lèi)"CConnectDB"。在該類(lèi)的源文件里添加對(duì)"ODBCSet.h"的引用:#include "ODBCSet.h"。在該類(lèi)的頭文件的"class CconnectDB"前添加class CODBCSet;并在該類(lèi)里添加公有型成員變量和函數(shù):

CDatabase m_dbData;
CODBCSet* m_pSet;
void CConnectDB::Initial()
{
 //打開(kāi)數(shù)據(jù)源RP97
 CString os=_T("odbc; dsn=RP97");
 m_dbData.Open(NULL,FALSE,FALSE,0);
 m_pSet=new CODBCSet(&m_dbData);
 //通過(guò)SQL結(jié)構(gòu)化查詢(xún)語(yǔ)言打開(kāi)RP97里的單據(jù)表
 CString sql="SELECT * FROM 單據(jù)表";
 m_pSet->Open(AFX_DB_USE_DEFAULT_TYPE,sql);
}


  (六)在Form上添加一個(gè)"測(cè)試"按鈕及其響應(yīng)函數(shù)OnTest():

void CNormalView::OnTest()
{
 CConnectDB connectDB;
 //執(zhí)行完Initial()后m_pSet指針才不為空,方可安全使用。
 connectDB.Initial();
 if(connectDB.m_pSet==NULL)
  return;
 connectDB.m_pSet->MoveFirst();
 CString str=connectDB.m_pSet->m_column3;
 AfxMessageBox(str);
}

  最后在該文件開(kāi)始處添加兩個(gè)引用:

#include "ConnectDB.h"
#include "ODBCSet.h"

  四、 運(yùn)行與測(cè)試

  編譯運(yùn)行程序,點(diǎn)擊"測(cè)試"按鈕,就會(huì)將"RP97"數(shù)據(jù)庫(kù)的"單據(jù)表"的第一條記錄的"報(bào)帳人"字段所在的內(nèi)容通過(guò)對(duì)話框彈出來(lái)。

  小結(jié):

  本程序的關(guān)鍵在于對(duì)數(shù)據(jù)庫(kù)指針m_pSet的獲取,當(dāng)類(lèi)CConnectDB 的成員函數(shù)Initial()被執(zhí)行完時(shí),m_pSet就已被獲取到了,而在此之前該指針是空的,是不能使用的,所以在實(shí)際應(yīng)用中必須保證在使用m_pSet之前調(diào)用過(guò)函數(shù)Initial()。當(dāng)m_pSet被獲取到之后,就可以想其他ODBC應(yīng)用程序一樣使用CrecordSet類(lèi)里的各種函數(shù)對(duì)數(shù)據(jù)庫(kù)進(jìn)行各種需要的操作和管理了。