一、 引言
数据库属于最流行的应用程序之一,几乎每个商业部门都使用数据库来记录、管理各种各样的数据。在VC下我们可以在创建工程时选择数据库支持,并选定数据源和相关的表,并选择CRecordView作为我们这个程序的基类,这样做可以毫不费力的将应用程序和数据库建立了关联,而几乎不用编什么代码,但这样做的前提是在新建工程时已明确知道用到哪个数据库,并且有相关的数据库。事实上我们往往有许多已做好的应用程序和类,其功能除了未和数据源建立关联外以基本满足要求,我们只要在其基础上添加ODBC接口,使之与数据库建立关联即可,这样做避免了与数据库无关部分代码的重新编写所造成的重复性操作,大大提高了代码的重用性和利用率。所以在普通程序上通过添加ODBC应用而与数据库建立关联的方法是完全行之有效的。
二、 ODBC技术
ODBC(Open Database Conectivity 开放式数据库互联)技术,作为Microsoft公司对数据库进行访问的标准应用程序接口(API)和Windows开放式服务体系结构OSA的一个重要组成部分已广为众多的Windows程序员所熟悉、认可。ODBC的工作依赖于数据库制造商提供的驱动程序,使用ODBC API的时候,Windows的ODBC管理程序,把数据库访问的请求传递给正确的驱动程序,驱动程序再使用SQL语句指示DBMS完成数据库访问工作,因此,ODBC的存在为我们开发应用数据库程序提供了非常强大的能力和灵活性。
三、 程序示例
(一)打开Visual C++,在"File"菜单上点选"New…",然后在弹出的"New"对话框中选定"MFC AppWizard(exe)"类的项目,"Project name"为Normal,按下OK键,下一Step 1屏幕中选"Single document"单文档支持,用到后面的选项除在最后一步选择"CFormView"作为本工程视类的基类外均为确省值,此时即可按下Finish键,结果系统将生成一个新的项目Normal。
我们就将此工程当做原有的工程,接下来我们便在此工程基础上对其添加ODBC应用,使该工程能同数据源建立关联,能对数据库中的数据进行操作和管理。
(二)打开"控制面板"上的"ODBC (32bits)",对数据源进行注册。为了使ODBC能与数据库一起工作,就必须把数据库注册到ODBC驱动程序管理器,这项工作可以通过定义一个DSN或数据源名字来完成。在弹出的"ODBC数据源管理器"中选择"User DSN"属性页,点击"Add…"按钮。选择"Microsoft Access Driver(*.mdb)"作为数据源的驱动器,点击"完成"按钮。在弹出的"ODBC Microsoft Access 97 Setup"对话框中在"Data Source Name:"栏添入RP97,"Description:"栏只起注释说明的作用,可以不填,然后点击"Select…"按钮,选择所要注册的数据源,然后点击"OK"就完成了对数据源的注册,到这一步,本机上的任意程序只要通过ODBC接口和数据源名"RP97"就能完成对数据库的访问了。
(三)在VC的"Workspace"活动窗口中选择"FileView"属性页,打开标准框架头文件"StdAfx.h",并在最后一个#include后面添加对"afxdb.h"的引用:#include <afxdb.h>
(四) 在"Workspace"活动窗口中选择"ClassView"属性页,在"Normal Classes"上右键,选"New Class…",在弹出的"New Class"对话框的"Base Class"栏选择"CRecordSet"做为新添加的类的基类,在"Name"栏填写类名"CODBCSet",点击"OK",在随后弹出的对话框的"ODBC"栏选择刚注册的"RP97"数据源,点击"OK"后选择该数据库的一个表,点击"OK"在"ClassView"里就多了一个以CRecordSet为基类的新类"CODBCSet"。下面三个函数完成了数据库各级元素的绑定工作:
CString CODBCSet::GetDefaultConnect()
{
return _T("ODBC;DSN=RP97");
}
CString CODBCSet::GetDefaultSQL()
{
return _T("[单据表]");
}
void CODBCSet::DoFieldExchange(CFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(CODBCSet)
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, _T("[单据ID]"), m_column1);
RFX_Text(pFX, _T("[单据名称]"), m_column2);
RFX_Text(pFX, _T("[报帐人]"), m_column3);
//}}AFX_FIELD_MAP
}
(五)按同样的方法再添加一个基于"generic CWnd"的新类"CConnectDB"。在该类的源文件里添加对"ODBCSet.h"的引用:#include "ODBCSet.h"。在该类的头文件的"class CconnectDB"前添加class CODBCSet;并在该类里添加公有型成员变量和函数:
CDatabase m_dbData;
CODBCSet* m_pSet;
void CConnectDB::Initial()
{
//打开数据源RP97
CString os=_T("odbc; dsn=RP97");
m_dbData.Open(NULL,FALSE,FALSE,0);
m_pSet=new CODBCSet(&m_dbData);
//通过SQL结构化查询语言打开RP97里的单据表
CString sql="SELECT * FROM 单据表";
m_pSet->Open(AFX_DB_USE_DEFAULT_TYPE,sql);
}
(六)在Form上添加一个"测试"按钮及其响应函数OnTest():
void CNormalView::OnTest()
{
CConnectDB connectDB;
//执行完Initial()后m_pSet指针才不为空,方可安全使用。
connectDB.Initial();
if(connectDB.m_pSet==NULL)
return;
connectDB.m_pSet->MoveFirst();
CString str=connectDB.m_pSet->m_column3;
AfxMessageBox(str);
}
最后在该文件开始处添加两个引用:
#include "ConnectDB.h"
#include "ODBCSet.h"
四、 运行与测试
编译运行程序,点击"测试"按钮,就会将"RP97"数据库的"单据表"的第一条记录的"报帐人"字段所在的内容通过对话框弹出来。
小结:
本程序的关键在于对数据库指针m_pSet的获取,当类CConnectDB 的成员函数Initial()被执行完时,m_pSet就已被获取到了,而在此之前该指针是空的,是不能使用的,所以在实际应用中必须保证在使用m_pSet之前调用过函数Initial()。当m_pSet被获取到之后,就可以想其他ODBC应用程序一样使用CrecordSet类里的各种函数对数据库进行各种需要的操作和管理了。