浅谈利用VC++对数据库的开发

2010-05-17 06:04张秋波
铁道勘察 2010年1期
关键词:对话框语句应用程序

张秋波

(中铁工程设计咨询集团有限公司济南设计院, 山东济南 250022)

1 开发环境的建立

使用AppWizard来创建MFC工程(选择工程→新建→工程菜单,这时弹出创建向导对话框(如图1)),工程命名为“张秋波”。

图1 工程菜单

在Step1中选择D基本对话框然后单击完成。

(1)在主对话框中设置其ID: IDD_MY_DIALOG,在工具的控制面板上选择List Control主对话框中拖出一个方框,点击右键选择Properties,设置其ID: IDC_LIST,并利用Class Wizard(类向导)设置member variable name(变量名)为“m_list”并添加相应的函数OnDblclkList、OnRclickList。然后利用工具的控制面板中的Button创建四个按钮,标题分别为:添加、修改、删除、查询,ID分别为:IDC_BUTTON_ADD、IDC_BUTTON_EDIT、IDC_BUTTON_DEL、IDC_BUTTON_SEARCH,并添加相应函数:OnButtonAdd、OnButtonDel、OnButtonEdit、OnButtonSearch。最后设置结果如图2所示。

图2 设置菜单

(2)在Dialog中再添加一个对话框(即设置新类),设置其ID为:IDD_DIALOG_ADD,标题为:添加/修改记录,其类名为CAddDlg,用于查询操作。在对话框上分别设置查询窗口:名称分别为:CategoryID:、CategoryName:、Description:、Picture:,输入窗口分别为:IDC_CategoryID、IDC_CategoryName、IDC_Description、IDC_Picture,其对应的变量名分别为:m_categoryid、m_categoryname、m_description,最后设置结果如图3。

图3 添加与修改

(3)在Dialog中再添加一个用于查询操作的对话框,方法同上两步,分别设置其ID、函数、变量名。鉴于篇幅这里不再赘述,最后设置结果如图4。

图4 查询

上面三步简单介绍了环境的建立过程(这里只介绍了一些主要操作的建立过程),下面介绍这些功能的实现过程。

2 实现步骤

2.1 链接数据库

(1)引入ADO库文件使用预处理指令#import

代码如下:#import "C:Program Filescommon filessystemadomsado15.dll" no_namespace rename("EOF","EndOfFile")要注意不能放在stdAfx.h文件的开头,而应该放在所有include指令的后面。否则在编译时会出错。程序在编译过程中,VC++会读出msado15.dll中的类型库信息,自动产生两个该类型库的头文件和实现文件msado15.tlh和msado15.tli(在您的Debug或Release目录下)。在这两个文件里定义了ADO的所有对象和方法,以及一些枚举型的常量等。我们的程序只要直接调用这些方法就行了。

(2)生成应用程序框架并初始化OLE/COM库环境

创建一个标准的MFC AppWizard(exe)应用程序,然后在使用ADO数据库的InitInstance函数中初始化OLE/COM库(因为ADO库是一个COM DLL库)。代码如下:

BOOL CMyDlg::OnInitDialog()

{::CoInitialize(NULL); //初始化OLE/COM库环境

CDialog::OnInitDialog();

ASSERT((IDM_ABOUTBOX & 0xFFF0)=IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX<0xF000);

CMenu*pSysMenu=GetSystemMenu(FALSE);

if (pSysMenu !=NULL)

{CString strAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if (!strAboutMenu.IsEmpty())

{pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}

SetIcon(m_hIcon, TRUE);

SetIcon(m_hIcon, FALSE);

m_font1.CreateFont(12, 0,0,0,FW_BOLD, 0,0,0,

DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,

DEFAULT_QUALITY, DEFAULT_PITCH |FF_DONTCARE, "宋体");

m_imagelist.Create(16,16,TRUE,2,2);

m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_YES));

m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_NO));

m_list.SetImageList(&m_imagelist,LVSIL_SMALL);

m_list.SetExtendedStyle(0x21);

m_list.GetHeaderCtrl()->SetFont(&m_font1);

m_list.SetBkColor(RGB(247,247,255));

m_list.SetTextColor(RGB(0,0,255));

m_list.SetTextBkColor(RGB(247,247,255));

m_list.InsertColumn(0,"CategoryID",LVCFMT_LEFT,120);

m_list.InsertColumn(1,"CategoryName",LVCFMT_CENTER,170);

m_list.InsertColumn(2,"Description",LVCFMT_CENTER,170);

m_list.InsertColumn(3,"Picture",LVCFMT_CENTER,150);

List("SELECT*FROM Categories");//显示此用户的数据

return TRUE;}

void CMyDlg::List(CString sql)//将SQL语句查询的结果显示在列表框中

{int nItem=0;

m_list.DeleteAllItems();

m_pRecordset.CreateInstance(_uuidof(Recordset));//初始化Recordset指针

try

{m_pRecordset->Open((_variant_t)sql,(IDispatch*)theApp.m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText);

while(!m_pRecordset->EndOfFile)//遍历所有记录

{if(!m_pRecordset->EndOfFile)

{nItem=m_list.InsertItem(0xffff,(char*)_bstr_t(m_pRecordset->GetCollect("CategoryID")));

m_list.SetItemText(nItem,0,(LPCTSTR)(_bstr_t)m_pRecordset->GetCollect("CategoryID"));

m_list.SetItemText(nItem,1,(LPCTSTR)(_bstr_t)m_pRecordset->GetCollect("CategoryName"));

m_list.SetItemText(nItem,2,(LPCTSTR)(_bstr_t)m_pRecordset->GetCollect("Description"));

m_list.SetItemText(nItem,3,(LPCTSTR)(_bstr_t)m_pRecordset->GetCollect("Picture"));}

m_pRecordset->MoveNext();//转到下一条记录}

m_pRecordset->Close();

m_pRecordset=NULL;}

catch (_com_error e)//异常处理

{AfxMessageBox(e.ErrorMessage());}}

BOOL CMyDlg::DestroyWindow()

{::CoUninitialize();

return CDialog::DestroyWindow();}

2.2 表中增加、删除、修改、查询操作的实现

(1)增加

void CAddDlg::OnOK()

{UpdateData();

try

{_variant_t RecordsAffected;

if(!m_bAddOrModify)//如果是添加记录的话就执行SQL语句进行添加

{theApp.m_strSQL="INSERT INTO Categories

(CategoryName, Description, Picture) values('"+m_categoryname+"','"+m_description+"','"+m_picture+"')";

theApp.m_pConnection->Execute((_bstr_t)theApp.m_strSQL,&RecordsAffected,adCmdText);

UpdateData(false);}

else //如果是修改记录的话就执行SQL语句进行数据库的更新

{UpdateData();

theApp.m_strSQL="update Categories set CategoryName='"+m_categoryname+

"',Description='"+m_description+"',Picture='"+m_picture+"' where Category

ID='"+m_strFlag+"'";

_variant_t RecordsAffected;

theApp.m_pConnection->Execute((_bstr_t)theApp.m_strSQL,&RecordsAffected,adCmdText);}

((CMyDlg*)AfxGetMainWnd())->List("SELECT * FROM Categories");; //更新列表框的显示

CDialog::OnOK();}

catch(_com_error e)

{AfxMessageBox(e.ErrorMessage());}}

BOOL CAddDlg::OnInitDialog()

{CDialog::OnInitDialog();

theApp.m_strSQL="select * from

Categories where CategoryID='"+m_categoryid+"' and

CategoryName='"+m_categoryname+"' and

Description='"+m_description+"' and

Picture='"+m_picture+"'";

_RecordsetPtr m_pRecordset;

switch(this->m_bAddOrModify) //根据主窗口转来的数据判断是否是添加记录还是修改。

{case 0:

SetWindowText("添加记录");

break;

case 1:

SetWindowText("修改记录");

try

{m_pRecordset.CreateInstance(_uuidof(Recordset));

m_pRecordset->Open((_variant_t)theApp.m_strSQL,_variant_t((IDispatch*)theApp.m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);

if(!m_pRecordset->EndOfFile)

{m_strFlag=(LPCTSTR)(_bstr_t)m_pRecordset->GetCollect("Flag");}

m_pRecordset->Close();}

catch(_com_error e)///捕捉异常

{AfxMessageBox(e.ErrorMessage());}

break;}

return TRUE; }

#include "AddDlg.h"

void CMyDlg::OnButtonAdd()

{CAddDlg dlgadd;

dlgadd.m_bAddOrModify=0; //添加记录的标志

dlgadd.DoModal();}

(2)删除

void CMyDlg::OnButtonDel()

{try

{POSITION pos=m_list.GetFirstSelectedItemPosition();

if(pos)//如果选中一行,则生成动态的sql语句

{int nItem=m_list.GetNextSelectedItem(pos);

theApp.m_strSQL="DELETE FROM [Order Details] WHERE ProductID in (select ProductID from Products where CategoryID='"+m_list.GetItemText(nItem,0)+"') DELETE FROM Products WHERE CategoryID='"+m_list.GetItemText(nItem,0)+"' DELETE FROM Categories WHERE CategoryID='"+m_list.GetItemText(nItem,0)+"' and CategoryName='"+m_list.GetItemText(nItem,1)+"' and Description like '"+m_list.GetItemText(nItem,2)+"'";

_variant_t RecordsAffected;

theApp.m_pConnection->Execute((_bstr_t)theApp.m_strSQL,&RecordsAffected,adCmdText);//执行此sql语句

List("SELECT * FROM Categories");}}

else

AfxMessageBox("请选择一行数据!");}

catch(_com_error e)

{AfxMessageBox(e.ErrorMessage());}}

(3)修改

void CMyDlg::OnButtonEdit()

{POSITION pos=m_list.GetFirstSelectedItemPosition();

if(pos)//如果选中一行

{int nItem=m_list.GetNextSelectedItem(pos);

CAddDlg dlgadd;

dlgadd.m_bAddOrModify=1; //修改

dlgadd.m_categoryid=m_list.GetItemText(nItem,0);

dlgadd.m_strFlag=m_list.GetItemText(nItem,0);

dlgadd.m_categoryname=m_list.GetItemText(nItem,1);

dlgadd.m_description=m_list.GetItemText(nItem,2);

dlgadd.m_picture=m_list.GetItemText(nItem,3);

dlgadd.DoModal();} }

(4)查询

#include "SearchDlg.h"

void CMyDlg::OnButtonSearch()

{CSearchDlg sd;

sd.DoModal();}

void CMyDlg::OnRadio4()

{UpdateData();

switch(m_radio)

{case 0:

theApp.m_strSQL="SELECT * FROM Categories";

break;

case 1:

theApp.m_strSQL="SELECT * FROM Categories WHERE YorN='N'";

break;

case 2:

heApp.m_strSQL="SELECT * FROM Categories WHERE YorN='Y'";

break;}

List(theApp.m_strSQL); }

最终运行结果如图5所示。

注:在操作过程中要注意备份数据库中的数据。

3 结束语

ADO模型包含了连接对象、命令对象、域对象、参数对象、记录集对象、错误对象等。对象之间又具有层次关系。在VC++中使用ADO访问数据库基本过程是:初始化COM库,引入ADO库文件,用Connection对象连接数据库,利用建立好的连接,通过利用Recordset对象取得结果记录集进行查询、处理。使用完毕后关闭连接释放对象。封装的ADO类应包括以下函数和数据结构:

(1)建立数据库连接函数;ADO连接数据库首先要用到Connection对象,它是到数据库的物理连接,管理着应用程序和数据库之间的通讯。对于大多数的数据库系统,每一个物理连接都需要耗费大量系统内存,是宝贵的系统资源,不可滥用。考虑到应用程序的效率,每一个数据库客户端都只用一个物理连接,并且应用程序结束后应该释放。

(2)关闭数据库连接函数。

(3)SQL查询语句函数Select();记录集的建立和查询结果得获取是影响应用程序得效率得关键问题。由于每一次查询结果都可能不一样,所以每个查询语句都要建立一个记录集对象。

(4)执行无返回结果的SQL语句函数Excute();实现对数据库的连接以及对数据库中表的增加、删除、修改、查询等基本操作。

本文只是笔者在工作过程中对VC++语言使用过程中的简单体会。通过开发一些小的程序对我们的工作会带来很多方便,能大大提高我们的工作效率。

[1] 韩 鹏.地理信息系统开发——MapObjects方法[M].武汉:武汉大学出版社,2004

[2] 刘 光.地理信息系统——组件开发篇[M].北京:中国电力出版社,2003

[3] 吕丹阳,等.Visual C++.NET数据库开发指南[M].北京:清华大学出版社,2002

猜你喜欢
对话框语句应用程序
重点:语句衔接
正常恢复虚拟机
删除Win10中自带的应用程序
Bootlace Worms’Secret etc.
What Is Beauty?
谷歌禁止加密货币应用程序
浅谈VB的通用对话框《CommonDialog》控件的使用
如何搞定语句衔接题
三星电子将开设应用程序下载商店
作文语句实录