《VC++数据库实验-实验七.doc》由会员分享,可在线阅读,更多相关《VC++数据库实验-实验七.doc(13页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、实验七 VC+环境下连接SQL Server数据库方法指导实验类型:设计型一、实验环境1Windows XP操作系统;2VC+6.0开发环境;3access 2003数据库管理系统。二、实验内容和要求利用VC开发应用程序,要求能够通过界面完成对数据库中数据的查询、插入、删除以及修改。三、实验原理VC访问access 数据库,常用的方法有两种:通过ODBC连接和通过ADO连接。下面分别介绍一下。采用ODBC方式要求先创建ODBC数据源,应用程序通过数据源与数据库连接;并且在创建应用程序时,只能是基于单文档或多文档,而无法直接创建基于对话框的应用程序。采用ADO方式无需创建数据源,应用程序可通过A
2、DO直接与数据库连接;ADO方式可以创建基于对话框的应用程序。两种方式都要在应用程序中添加代码以完成相应的初始化功能。四、实验步骤下面介绍基于ADO方式的实验步骤。1 构建数据库(1)在access2003中创建数据库student,该数据库中有学生表s用来存放学生信息。s表的结构如下:属性名类型是否为主键允许空备注snochar(8)是学号snamevarchar(10)否姓名ageint否年龄deptchar(4)否所在系号commentvarchar(8)否评语 s表的创建方法在此不详述。2基于ADO方式的实验步骤此例中所用数据库与上例中相同;此例中无需创建数据源。(1)创建VC应用程序
3、l 打开VC+6.0,新建工程。选择MFC AppWizard(exe),工程名为exec2,存放在D盘实验文件夹里。点击“确定”,在弹出的窗口中选择“基本对话框”,以后的步骤没有需要修改的地方,可以直接点击“完成。”这样一个基于基本对话框的工程就创建好了。(2)界面设计l 在工作区左边的树型结构中,选择ResourceView,展开Dialog节点,双击IDD_EXEC2_DIALOG,打开该对话框。在这里添加所需控件。如图17所示。图17l 为编辑框和列表框添加变量。在界面右键单击,选择“建立类向导”,弹出如图18所示窗口。图18本例中需要为编辑框IDC_AGE, IDC_COMMENT,
4、 IDC_DEPT, IDC_NAME, IDC_SNO,列表框IDC_LIST添加变量。以IDC_AGE为例,点击“ADD Variable”弹出如图19所示窗口。图19这里变量名为m_age,类型可从下拉框里选。添加变量完成之后类向导如图20所示。图20l 为按钮添加函数,双击按钮可为其添加函数,在exec2Dig.cpp文件里。(3)与ADO相关的代码设计l 引入ADO库文件,使用ADO前必须在工程的StdAfx.h头文件里用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下所示:/加入ADO支持库#import c:program filescommon fil
5、essystemadomsado15.dll no_namespace rename (EOF, adoEOF) l 定义ADO连接变量指针,在exec2.h文件的class CExec2App : public CwinApp方法中添加代码如下: / 定义ADO连接变量指针_ConnectionPtrm_pConnection;该指针为整个应用程序共享,所以放在public下面。l 定义ADO连接、命令、记录集变量指针,在exec2Dlg.h文件的class CExec2Dlg : public CDialog方法中添加如下代码: / 定义ADO连接、命令、记录集变量指针_Connectio
6、nPtrm_pConnection;_CommandPtrm_pCommand;_RecordsetPtrm_pRecordset;该指针为整个应用程序共享,所以放在public下面。l 初始化OLE/COM库环境。必须注意的是,ADO库是一组COM动态库,这意味应用程序在调用ADO前,必须初始化OLE/COM库环境。在MFC应用程序里,一个比较好的方法是在应用程序主类的InitInstance成员函数里初始化OLE/COM库环境。在本例中,在exec2.cpp文件的BOOL CExec2App:InitInstance()成员函数里添加如下代码:/初始化COM,创建ADO连接等操作AfxOl
7、eInit();m_pConnection.CreateInstance(_uuidof(Connection);/在ADO操作中建议语句中要常用try.catch()来捕获错误信息,/因为它有时会经常出现一些想不到的错误try /打开本地 Sql Server库student m_pConnection-Open(Provider=Microsoft.Jet.OLEDB.4.0;DataSource=student.mdb,adModeUnknown);,adModeUnknown);/DataSource后是数据库名/这里使用的windows验证,没有设置用户名和密码,catch(_com
8、_error e)AfxMessageBox(数据库连接失败!);return FALSE; l 在exec2Dlg.cpp文件中添加代码。在#endif下面添加如下代码: extern CExec2App theApp; / 在此引用应用类中的theApp来获取库连接指针在BOOL CExec2Dlg:OnInitDialog()函数中添加如下代码:/ TODO: Add extra initialization here/使用ADO创建数据库记录集m_pRecordset.CreateInstance(_uuidof(Recordset);/ 在ADO操作中建议语句中要常用try.catc
9、h()来捕获错误信息,/ 因为它有时会经常出现一些想不到的错误trym_pRecordset-Open(SELECT * FROM s, / 查询s表中所有字段theApp.m_pConnection.GetInterfacePtr(), / 获取库接库的IDispatch指针adOpenDynamic,adLockOptimistic,adCmdText);catch(_com_error *e)AfxMessageBox(e-ErrorMessage();l 至此,与ADO相关的代码都已添加完了。下面在exec2Dlg.cpp文件中添加应用代码。(4)与功能相关的代码设计l 在界面上用到列
10、表框,当鼠标点击列表框的某一行时,其中的数据能够在编辑框中显示出来,这要用到列表框的一个函数。添加此函数的方法如下:摁住Ctrl和w键,进入类向导,如图21所示。图21选择IDC_LIST,在右边的Messages下面选择LBN_SELCHANGE,然后点击“Add Function”按钮,最后点击“确定”按钮,即为列表框添加了此函数。具体代码如下:/名称:OnSelchangeList/功能:当每次选择新的记录时,都会移动指针到新的记录位置并将值显示出来void CExec2Dlg:OnSelchangeList() int curSel = m_list.GetCurSel();_vari
11、ant_t var,varIndex;if(curSel MoveFirst();m_pRecordset-Move(long(curSel);var = m_pRecordset-GetCollect(sname);if(var.vt != VT_NULL)m_sname = (LPCSTR)_bstr_t(var);var = m_pRecordset-GetCollect(age);if(var.vt != VT_NULL)m_age=(LPCSTR)_bstr_t(var);var = m_pRecordset-GetCollect(sno);if(var.vt != VT_NULL)
12、m_sno = (LPCSTR)_bstr_t(var);var = m_pRecordset-GetCollect(dept);if(var.vt != VT_NULL)m_dept = (LPCSTR)_bstr_t(var);var = m_pRecordset-GetCollect(comment);if(var.vt != VT_NULL)m_comment = (LPCSTR)_bstr_t(var);UpdateData(false);catch(_com_error *e)AfxMessageBox(e-ErrorMessage();l 将数据库中的数据显示在列表框中,添加函数
13、ListData()。添加的方法是,在工作区左边的树型结构中,选择ClassView,右键单击CExec2Dlg,在弹出的菜单中选择Add Member Function,出现如图22所示的窗口,类型为void,函数描述为ListData()。图22此函数的具体代码如下:/名称:ListData/功能:将数据库中的数据显示在列表框中void CExec2Dlg:ListData() _variant_t var;CString strname,strage,strsno,strdept,strcom;/清空列表框m_list.ResetContent();strname=strage=strs
14、no=strdept=strcom=;/在ADO操作中建议语句中要常用try.catch()来捕获错误信息,/因为它有时会经常出现一些想不到的错误。tryif(!m_pRecordset-BOF)m_pRecordset-MoveFirst();elseAfxMessageBox(表内数据为空);return;/ 读入库中各字段并加入列表框中while(!m_pRecordset-adoEOF)var = m_pRecordset-GetCollect(sno);if(var.vt != VT_NULL)strsno = (LPCSTR)_bstr_t(var);var = m_pRecord
15、set-GetCollect(sname);if(var.vt != VT_NULL)strname = (LPCSTR)_bstr_t(var);var = m_pRecordset-GetCollect(age);if(var.vt != VT_NULL)strage = (LPCSTR)_bstr_t(var);var = m_pRecordset-GetCollect(dept);if(var.vt != VT_NULL)strdept = (LPCSTR)_bstr_t(var);var = m_pRecordset-GetCollect(comment);if(var.vt !=
16、VT_NULL)strcom = (LPCSTR)_bstr_t(var);m_list.AddString( strsno + - +strname + - +strage+ - + strdept+ - + strcom);m_pRecordset-MoveNext();/ 默认列表指向第一项,同时移动记录指针并显示m_list.SetCurSel(0);OnSelchangeList();catch(_com_error *e)AfxMessageBox(e-ErrorMessage();l 插入按钮对应的函数代码如下:/名称:OnWritedata/功能:将编辑框中输入的学生信息插入到
17、s表中void CExec2Dlg:OnWritedata() UpdateData();if(m_sname = | m_sno = )AfxMessageBox(学号和姓名信息不能为空!);return;/在ADO操作中建议语句中要常用try.catch()来捕获错误信息,/因为它有时会经常出现一些想不到的错误。try/ 写入各字段值m_pRecordset-AddNew();m_pRecordset-PutCollect(sno, _variant_t(m_sno);m_pRecordset-PutCollect(sname, _variant_t(m_sname);m_pRecords
18、et-PutCollect(age, atol(m_age);m_pRecordset-PutCollect(dept, _variant_t(m_dept);m_pRecordset-PutCollect(comment, _variant_t(m_comment);m_pRecordset-Update();AfxMessageBox(插入成功!);/ 更新显示其库内容int nCurSel = m_list.GetCurSel();ListData();m_list.SetCurSel(nCurSel);/ 移动记录指针到新的位置OnSelchangeList();catch(_com_
19、error *e)AfxMessageBox(e-ErrorMessage();l 修改按钮对应的函数代码如下:/名称:OnModify/功能:修改学生信息void CExec2Dlg:OnModify() UpdateData(); / 更新对话框数据if(m_list.GetCount() = 0)AfxMessageBox(表中记录数为空!);return;else if(m_list.GetCurSel() m_list.GetCount()m_list.SetCurSel(0);/ 修改当前记录的字段值trym_pRecordset-PutCollect(sno, _variant_
20、t(m_sno);m_pRecordset-PutCollect(sname, _variant_t(m_sname);m_pRecordset-PutCollect(age, atol(m_age);m_pRecordset-PutCollect(dept, _variant_t(m_dept);m_pRecordset-PutCollect(comment, _variant_t(m_comment);m_pRecordset-Update();/ 重新读入库记录更新显示int nCurSel = m_list.GetCurSel();ListData();m_list.SetCurSel
21、(nCurSel);/ 移动记录指针到新的位置OnSelchangeList();catch(_com_error *e)AfxMessageBox(e-ErrorMessage();l 删除按钮对应的函数代码如下:/名称:OnDelete/功能:删除选中的学生信息void CExec2Dlg:OnDelete() if(m_list.GetCount() = 0)return;else if(m_list.GetCurSel() m_list.GetCount()m_list.SetCurSel(0);try/ 删除当前行记录m_pRecordset-Delete(adAffectCurre
22、nt);m_pRecordset-Update();/ 删除列表中当前值int nCurSel = m_list.GetCurSel();m_list.DeleteString(nCurSel);if(nCurSel = 0 & (m_list.GetCount() != 0)m_list.SetCurSel(nCurSel);else if(m_list.GetCount() != 0)m_list.SetCurSel(nCurSel-1);/ 移动记录指针到新的位置OnSelchangeList();catch(_com_error *e)AfxMessageBox(e-ErrorMess
23、age();l 查询按钮对应的函数代码如下:/名称:OnQuery() /功能:按照学号和姓名查询学生信息,如果只输入学号则只按照学号查询/只输入姓名则只按照姓名查询,两者都没有输入则查询所有学生信息void CExec2Dlg:OnQuery() UpdateData(TRUE);/构造Sql语句/为简单考虑,这里只把学号和姓名作为查询条件CString strSql;if(m_sname != & m_sno != )strSql.Format(SELECT * FROM s WHERE sname = %s AND sno = %s,m_sname,m_sno);else if(m_sn
24、ame != & m_sno = )strSql.Format(SELECT * FROM s WHERE sname = %s,m_sname);else if(m_sname = & m_sno != )strSql.Format(SELECT * FROM s WHERE sno = %s,m_sno);elsestrSql = SELECT * FROM s;try/先关闭已经打开的记录集对象m_pRecordset-Close();/根据新的Sql查询语句,重新打开记录集对象m_pRecordset-Open(strSql.AllocSysString(), theApp.m_pCo
25、nnection.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText);catch(_com_error *e)AfxMessageBox(e-ErrorMessage();/将查询后得到的新记录集显示出来ListData();l 刷新按钮对应的函数代码如下:/名称:OnRefresh/功能:刷新编辑框和列表框void CExec2Dlg:OnRefresh() m_sno=;m_sname=;m_age=;m_dept=;m_comment=;m_list.ResetContent();UpdateData(false);(5)运行结果图23五、实验总结1. 通过上面两个例子可以看出,基于ODBC的连接需要事先建立数据源,但连接时代码相对简单;基于ADO的连接不需要建立数据源,连接代码比较复杂。2. vc中与数据库相关的控件比较多,在第二个例子中仅使用了ListBox一种,实际上常用的还有ListCtrl,DataGrid等,这里不能一一介绍,同学们用到时可以再学习。
限制150内