《数据库编程》课件.ppt
第9章数据库编程,9.1数据库概述 9.2ODBC数据库编程 9.3数据库编程常用技巧 9.4数据库相关的ActiveX控件,9.1数据库概述,数据库和DBMS 数据库是指以一定的组织形式存放在计算机存储介质上的相互关联的数据的集合。例如,把一个学校的教师、学生和课程等数据有序地组织起来,存储在计算机磁盘上,就构成了一个数据库。为了有效地管理数据库,常常需要一些数据库管理系统(DBMS)为用户提供对数据库操作的各种命令、工具及方法,包括数据库的建立和记录的输入、修改、检索、显示、删除和统计等。流行的DBMS都提供了一个SQL接口。SQL 作为用来在DBMS中访问和操作的语言,SQL(结构化查询语言)语句分为两类:一是DDL(Data Definition Language,数据定义语言)语句,它是用来创建表、索引等,另一是DML(Data Manipulation Language,数据操作语言)语句,这些语句是用来读取数据、更新数据和执行其他类似操作的语句。,9.1数据库概述,ODBC、DAO和OLE DB ODBC(开放数据库连接)、DAO(数据访问对象)及OLE DB(OLE数据库)三种数据库方式,使应用程序从特定的数据管理系统(DBMS)脱离出来。ODBC提供应用程序接口(API),使任何一个数据库都可以通过ODBC驱动器与指定的DBMS相联。程序就可通过调用ODBC驱动管理器中相应的驱动程序达到管理数据库的目的。DAO使用Jet数据库引擎形成一系列的数据访问对象:数据库对象、表和查询对象、记录集对象等。可以打开一个Access数据库文件(MDB文件),也可直接打开一个ODBC数据源以及使用Jet引擎打开一个ISAM(被索引的顺序访问方法)类型的数据源(dBASE、FoxPro、Paradox、Excel或文本文件)。OLE DB试图提供一种统一的数据访问接口,并能处理除了标准关系型数据库中的数据之外,还能处理包括邮件数据、Web上的文本或图形、目录服务以及主机系统中的IMS和VSAM数据。OLE DB提供一个数据库编程COM接口,使得数据的使用者可以使用同样的方法访问各种数据,而不用考虑数据的具体存储地点、格式或类型。这个COM接口与ODBC相比,其健壮性和灵活性要高得多。,9.2 ODBC数据库编程,MFC AppWizard使用ODBC一般过程 构造数据库数据库表与表之间的关系构成了一个数据库。用Microsoft Access 创建一个数据库Student.mdb,暂包含一个数据表score,如表。在表中包括上、下两部分内容,上部分是数据表的记录内容,下部分是数据表的结构内容。,9.2 ODBC数据库编程,创建ODBC数据源 如果没有ODBC组件,当安装Visual C+的同时也会装上ODBC程序。它不是出现在程序组中,出现在系统的“控制面板”管理工具中,如图。双击ODBC图标,进入ODBC数据源管理器。可以设置ODBC数据源的一些信息。“用户DSN”页面是定义自己在本地计算机使用的数据源名,如图。,9.2 ODBC数据库编程,创建用户DSN的过程如下。(1)单击添加,在对话框中选择要添加用户数据源的驱动程序,这里选择“Microsoft Access Driver”,如图。(2)单击完成,单击选择按钮将前面创建的数据库调入,如图。,9.2 ODBC数据库编程,(3)单击确定,刚才创建的用户数据源被添加在“ODBC数据源管理器”的“用户数据源”列表中。如图。,9.2 ODBC数据库编程,在MFC AppWizard中选择数据源 用MFC AppWizard创建一个支持数据库的文档应用程序,如下面的过程。(1)用MFC AppWizard创建一个单文档应用程序Ex_ODBC。(2)在向导的第2步对话框中加入数据库的支持,如图。,9.2 ODBC数据库编程,在对话框中可以选择对数据库的不同支持,其中各选项的含义如表。,9.2 ODBC数据库编程,(3)选中“数据库查看使用文件支持”项,单击Data Source,从中选择ODBC的数据源“Database Example For VC+”,如图。(4)单击OK,如图,从中选择要使用的表score。,9.2 ODBC数据库编程,(5)单击OK,又回到了向导的第2步对话框。(6)单击完成。开发环境自动打开表单视图CEx_ODBCView的对话框资源模板IDD_EX_ODBC_FORM以及相应的对话框编辑器。(7)编译并运行,如图。,记录浏览按钮,9.2 ODBC数据库编程,设计浏览记录界面 按照图所示的布局,为表单对话框资源模板添加所表所示的控件。,9.2 ODBC数据库编程,(2)按快捷键Ctrl+W,切换到Member Variables页面,在Class name框中选择CEx_ODBCView,为上述控件添加相关联的数据成员。这里添加的控件变量都是由系统自动定义的,并与数据表字段相关联的。例如,双击IDC_STUNO,在弹出的“Add Member Variable”(添加类成员变量)对话框中的成员变量下拉列表中选择要添加的成员变量名m_pSet-m_studentno,选择后,控件变量的类型将自动设置,如图。,9.2 ODBC数据库编程,(3)按照上一步骤的方法,为下表的其他控件依次添加相关联的成员变量。控件变量的范围和大小应与数据表中的字段一一对应。如图。,9.2 ODBC数据库编程,(4)编译运行并测试,如图。,9.2 ODBC数据库编程,9.2.2 ODBC数据表更新 在生成的CEx_ODBCView类中,包含一个指向CEx_ODBCSet对象的指针m_pSet。该指针与用户的表相关联,是由MFC AppWizard建立的,当数据表的字段更新后,例如,若Access将score数据表添加一个“备注”字段名,并关闭Access后,就需要为Ex_ODBC重新来指定数据表,其步骤如下:(1)按快捷键Ctrl+W,切换到“Member Variables”页面。(2)在“Class name”的下拉列表中选择“CEx_ODBCSet”,如图。Update Columns 重新指定与CRecordSet类相关的表,Bind All指定表的字段的绑定,即为字段重新指定默认的关联变量。,9.2 ODBC数据库编程,(3)单击Update Columns,选择ODBC数据源“Database Example For VC+”,如图。(4)单击OK,如图,从中选择要使用的表。,9.2 ODBC数据库编程,(5)单击OK,如图。(6)单击Bind All,MFC Wizard将自动为字段落添加相关联的变量。需要说明的是,在按Bind All按钮绑定前最好将已有的字段关联变量删除,以保证数据表字段名更改或删除后与变量绑定的正确性。,9.2 ODBC数据库编程,CRecordSet 类基本操作 查询记录 先看一个示例,该示例在前面的Ex_ODBC的表单中添加一个编辑框和一个查询按钮,单击查询,将按编辑框中的学号内容对数据表进行查询,并将查找到的记录显示在前面添加的控件中。示例的过程如下:(1)打开Ex_ODBC应用程序的表单资源,按图8所示的布局添加控件,其中添加的编辑框ID号设为IDC_EDIT_QUERY,“查询”按钮的ID号设为IDC_BUTTON_QUERY。,9.2 ODBC数据库编程,(2)打开MFC ClassWizard,为控件IDC_EDIT_QUERY添加关联变量m_strQuery。(3)在CEx_ODBCView类中添加按钮控件IDC_BUTTON_QUERY的BN_CLICKED消息映射,在映射函数中添加代码:void CEx_ODBCView:OnButtonQuery()UpdateData();m_strQuery.TrimLeft();if(m_strQuery.IsEmpty()MessageBox(要查询的学号不能为空!);return;if(m_pSet-IsOpen()m_pSet-Close();/如果记录集打开,则先关闭m_pSet-m_strFilter.Format(studentno=%s,m_strQuery);/studentno是score表的字段名,用来指定查询条件m_pSet-m_strSort=course;/course是score表的字段名,用来按course字段从小到大排序m_pSet-Open();if(!m_pSet-IsEOF()/如果打开记录集有记录UpdateData(FALSE);/自动更新表单中控件显示的内容elseMessageBox(没有查到你要找的学号记录!);,9.2 ODBC数据库编程,(4)编译运行并测试,如图。,9.2 ODBC数据库编程,增加记录 增加记录是使用AddNew函数,但要求数据库必须是以“可增加”的方式打开的。下面的代码是在表的末尾增加新记录:m_pSet-AddNew();/在表的末尾增加新记录m_pSet-SetFieldNull(,9.2 ODBC数据库编程,修改记录 函数CRecordSet:Edit可以用来修改记录,例如:m_pSet-Edit();/修改当前记录m_pSet-m_name=刘向东;/修改当前记录字段值.m_pSet-Update();/将修改结果存入数据库m_pSet-Requery();撤消操作 如果用户在进行增加或者修改记录后,希望放弃当前操作,则在调用CRecordSet:Update()函数之前调用CRecordSet:Move(AFX_MOVE_REFRESH)来撤消操作,便可恢复在增加或修改操作之前的当前记录。,9.3数据库编程常用技巧,显示记录总数和当前记录号 Ex_ODBC的记录浏览过程中,不能知道表中的记录总数及当前的记录位置,必须将这些信息显示出来。这时就需要使用CRecordset类的成员函数GetRecordCount和GetStatus用来获得表中的记录总数和当前记录的索引,原型:long GetRecordCount()const;void GetStatus(CRecordsetStatus,9.3数据库编程常用技巧,(3)用ClassWizard为CEx_ODBCView类添加OnCommand消息处理函数,添加代码:BOOL CEx_ODBCView:OnCommand(WPARAM wParam,LPARAM lParam)CString str;CMainFrame*pFrame=(CMainFrame*)AfxGetApp()-m_pMainWnd;/获得主框架窗口的指针CStatusBar*pStatus=,9.3数据库编程常用技巧,(4)在CEx_ODBCView的OnInitialUpdate函数处添加下列代码:void CEx_ODBCView:OnInitialUpdate()m_pSet=(5)在Ex_ODBCView.cpp文件的开始处增加下列语句:#include“MainFrm.h”(6)将MainFrm.h文件中的保护型变量m_wndStatusBar变成公共变量。(7)编译运行并测试。,9.3数据库编程常用技巧,9.3.2 编辑记录 下面的过程是在Ex_ODBC的表单视图中增加三个按钮:添加、修改和删除,如图。单击添加或修改按钮都将弹出一个如图的对话框,在对话框中对数据进行编辑后,单击确定按钮使操作有效。,9.3数据库编程常用技巧,(1)切换到ResourceView页面,打开用于表单视图CEx_ODBCView的对话框资源IDD_EX_ODBC_FORM。向表单中添加三个按钮:添加、修改和删除。(2)添加一个对话框资源,打开属性对话框将其字体设置为“宋体9号”,标题定为“学生课程成绩表”,ID号设为IDD_SCORE_TABLE。(3)将表单中的控件复制到对话框中。(4)将OK和Cancel的标题改为“确定”和“取消”。图中具有3D效果的竖直线是用静态图片控件(属性为Frame,Etched)构造的。(5)双击对话框模板或按Ctrl+W快捷键,为对话框资源IDD_SCORE_TABLE创建一个对话框类CScoreDlg。(6)打开Member Variables标签,在Class name中选择CScoreDlg,选中所需的控件ID号,双击鼠标或单击Add Variables按钮。为控件添加控件变量,如图。,9.3数据库编程常用技巧,(7)用MFC ClassWizard为CScoreDlg添加IDOK按钮的BN_CLICKED的消息映射,代码:void CScoreDlg:OnOK()UpdateData();m_strStudentNO.TrimLeft();m_strCourseNO.TrimLeft();if(m_strStudentNO.IsEmpty()MessageBox(学号不能为空!);else if(m_strCourseNO.IsEmpty()MessageBox(课程号不能为空!);elseCDialog:OnOK();(8)为CEx_ODBCView类中的三个按钮,添加代码:void CEx_ODBCView:OnRecAdd()CScoreDlg dlg;if(dlg.DoModal()=IDOK)m_pSet-AddNew();m_pSet-m_course=dlg.m_strCourseNO;m_pSet-m_studentno=dlg.m_strStudentNO;m_pSet-m_score=dlg.m_fScore;m_pSet-m_credit=dlg.m_fCredit;m_pSet-Update();m_pSet-Requery();,9.3数据库编程常用技巧,void CEx_ODBCView:OnRecEdit()CScoreDlg dlg;dlg.m_strCourseNO=m_pSet-m_course;dlg.m_strStudentNO=m_pSet-m_studentno;dlg.m_fScore=m_pSet-m_score;dlg.m_fCredit=m_pSet-m_credit;if(dlg.DoModal()=IDOK)m_pSet-Edit();m_pSet-m_course=dlg.m_strCourseNO;m_pSet-m_studentno=dlg.m_strStudentNO;m_pSet-m_score=dlg.m_fScore;m_pSet-m_credit=dlg.m_fCredit;m_pSet-Update();UpdateData(FALSE);,9.3数据库编程常用技巧,void CEx_ODBCView:OnRecDel()CRecordsetStatus status;m_pSet-GetStatus(status);m_pSet-Delete();if(status.m_lCurrentRecord=0)m_pSet-MoveNext();elsem_pSet-MoveFirst();UpdateData(FALSE);(9)在Ex_ODBCView.cpp文件的开始处增加下列语句:#include“ScoreDlg.h”(10)编译运行并测试。,9.3数据库编程常用技巧,处理多个表 用Microsoft Access 为数据库Student.mdb添加一个数据表course,如表所示。表中上部分是数据表的记录内容,下部分是数据表的结构内容。,9.3数据库编程常用技巧,示例的具体步骤如下:(1)打开前面的单文档应用程序Ex_ODBC。(2)按快捷键Ctrl+W。单击Add Class,选择“New”。(3)指定CRecordSet的派生类CCourseSet,如图。,9.3数据库编程常用技巧,(4)单击OK,弹出“Database Options”对话框,图9.7所示。(5)选择ODBC的数据源“Database Example For VC+”,单击OK,选择要使用的表course。(6)单击OK,单击确定,系统自动为生成CCodeSet类所需要的代码。(7)将工作区切换到ResourceView页面,打开对话框资源IDD_STU_TABLE。按图所示的控件布局,向对话框添加一个组合框控件和三个用于显示课程名称、课时数和开课学期数据的静态文本控件。,9.3数据库编程常用技巧,(8)打开Member Variables页面,在Class name中选择CStuDlg,选中所需的控件ID号,双击鼠标或单击Add Variables按钮。再为控件添加控件变量。,9.3数据库编程常用技巧,(9)切换到Messsage Maps页面,为CScoreDlg中增加WM_INITDIALOG的消息映射,并添加下列代码:BOOL CScoreDlg:OnInitDialog()CDialog:OnInitDialog();/将课程信息表的课程号添加到组合框中CCourseSet cSet;cSet.Open();while(!cSet.IsEOF()m_comboNO.AddString(cSet.m_courseno);cSet.MoveNext();if(cSet.IsOpen()cSet.Close();/确定组合框的当前选择项m_strCourseNO.TrimLeft();if(!m_strCourseNO.IsEmpty()m_strNO=m_strCourseNO;UpdateData(FALSE);OnSelchangeComboNo();return TRUE;/return TRUE unless you set the focus to a control,9.3数据库编程常用技巧,(10)为控件IDC_COMBO_NO增加CBN_SELCHANGE的消息映射,添加代码:void CScoreDlg:OnSelchangeComboNo()int nIndex=m_comboNO.GetCurSel();if(nIndex=CB_ERR)return;CString str;m_comboNO.GetLBText(nIndex,str);/根据课程号查找course表中的记录CCourseSet cSet;cSet.m_strFilter.Format(courseno=%s,str);cSet.Open();if(!cSet.IsEOF()/如果打开记录集有记录m_strNO=m_strCourseNO=str;m_strName=cSet.m_cname;m_strHours.Format(%d,cSet.m_hours);m_strOpen.Format(%d,cSet.m_copen);m_fScore=cSet.m_credit;UpdateData(FALSE);if(cSet.IsOpen()cSet.Close();,9.3数据库编程常用技巧,(11)在ScoreDlg.cpp文件的开始处增加下列语句:#include ScoreDlg.h#include CourseSet.h“(12)编译运行并测试。当单击修改按钮时,弹出如图所示的对话框。,9.3数据库编程常用技巧,字段操作 CRecordSet类中的成员变量m_nFields(用于保存数据表的字段个数)和成员函数GetODBCFieldInfo及GetFieldValue可以简化多字段的访问操作。GetODBCFieldInfo函数用来数据表中的字段信息,其函数原型如下:void GetODBCFieldInfo(short nIndex,CODBCFieldInfo,9.3数据库编程常用技巧,例Ex_Field 多个字段的编程操作。(1)创建一个基于CScrollView类的单文档应用程序Ex_Field。(2)为数据表course创建一个CRecordSet的派生类CCourseSet,(3)在CEx_FieldView:OnDraw函数中添加下列代码:void CEx_FieldView:OnDraw(CDC*pDC)CEx_FieldDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);TEXTMETRIC tm;pDC-GetTextMetrics(,9.3数据库编程常用技巧,/显示记录CString str;while(!cSet.IsEOF()x=0;y+=nLineHeight;for(UINT i=0;iTextOut(x,y,str);x+=nWidth;cSet.MoveNext();cSet.Close();/设置视图滚动大小CSize sizeTotal;sizeTotal.cx=x+nWidth;sizeTotal.cy=y+nLineHeight;SetScrollSizes(MM_TEXT,sizeTotal);,9.3数据库编程常用技巧,(4)在Ex_FieldView.cpp文件的前面添加CCourseSet类的包含语句:#include Ex_FieldDoc.h#include Ex_FieldView.h#include CourseSet.h“(5)编译运行,结果如图所示。,9.4数据库相关的ActiveX控件,使用MSFlexGrid控件 将控件的类添加到项目中(1)选择“工程”“添加工程”“Components and Controls.”,如图。(2)双击“Registered ActiveX Controls”项。在列表中找到Micorsoft FlexGrid Control,如图。单击更多信息可以获得该控件的帮助内容。,9.4数据库相关的ActiveX控件,(3)在该控件双击鼠标。单击确定,如图。单击OK 接受所有的类。(4)单击结束按钮关闭“Components and Controls Gallery”对话框。,9.4数据库相关的ActiveX控件,向对话框添加MSFlexGrid控件 打开表单IDD_EX_ODBC_FORM,看到上述控件已添加到对话框编辑器的控件工具栏中,如图。通过对话框编辑器可以方便地添加MSFlexGrid控件。修改MSFlexGrid控件属性 在IDD_EX_ODBC_FORM表单资源添加MSFlexGrid控件,右击该控件,选择“属性”或“Properties MSFlexGrid Object”命令均可打开该控件的属性对话框,如图。,添加的控件,9.4数据库相关的ActiveX控件,编程控制(1)保留默认的属性及其控件标识IDC_MSFLEXGRID1。(2)在CEx_ODBCView类中为刚才添加的MSFlexGrid控件增加一个CMSFlexGrid类成员变量m_MSFGrid,并在CEx_ODBCView类的OnInitialUpdate函数中添加代码:void CEx_ODBCView:OnInitialUpdate()m_pSet-MoveFirst();m_MSFGrid.SetCols(m_pSet-m_nFields+1);/根据字段个数,设置单元格的最大列数m_MSFGrid.SetRows(m_pSet-GetRecordCount()+1);/根据记录数,设置单元格的最大行数m_MSFGrid.SetColWidth(-1,1440);/将所有的单元格都设为相同的列宽。-1表示所有的列,列宽单位为一个点的/1/20(一个点是1/72英寸),也就是说,1440刚好为1英寸。/定义单元格的表头m_MSFGrid.SetRow(0);m_MSFGrid.SetCol(0);/定位到(0,0)单元格m_MSFGrid.SetText(记录号);/设置其显示内容m_MSFGrid.SetCellAlignment(4);/设置单元格对齐方式,4表示水平和垂直居中CODBCFieldInfo field;,9.4数据库相关的ActiveX控件,for(UINT i=0;im_nFields;i+)m_MSFGrid.SetRow(0);m_MSFGrid.SetCol(i+1);m_pSet-GetODBCFieldInfo(i,field);/获取指定字段信息m_MSFGrid.SetText(field.m_strName);m_MSFGrid.SetCellAlignment(4);int iRow=1;while(!m_pSet-IsEOF()/将表的记录内容显示在单元格中CString str;str.Format(记录%d,iRow);m_MSFGrid.SetRow(iRow);m_MSFGrid.SetCol(0);m_MSFGrid.SetText(str);m_MSFGrid.SetCellAlignment(4);for(UINT i=0;im_nFields;i+)m_MSFGrid.SetRow(iRow);m_MSFGrid.SetCol(i+1);m_pSet-GetFieldValue(i,str);m_MSFGrid.SetText(str);m_MSFGrid.SetCellAlignment(4);iRow+;m_pSet-MoveNext();m_MSFGrid.SetRow(1);m_MSFGrid.SetCol(1);m_pSet-MoveFirst();,9.4数据库相关的ActiveX控件,(3)编译运行,如图。,9.4数据库相关的ActiveX控件,RemoteData和DBGrid控件 RemoteData控件 RemoteData控件在远程数据对象(RDO)和数据识别的被绑定的控件之间提供了接口。通过RemoteData控件,能够:建立起与基于其本身属性的数据源的连接。创建RDO的结果集。把当前行的数据传送给相应被绑定的控件。允许对当前行指针进行定位。将对被绑定的控件所做的任何更改反传给数据源。下面来介绍RemoteData控件的使用,其步骤如下:(1)打开Ex_ODBC表单资源IDD_EX_ODBC_FORM。(2)在表单资源中右击鼠标,选择“Insert Active Control”,如图。,9.4数据库相关的ActiveX控件,(3)在控件列表中选择RemoteData控件,单击确定。上述添加控件的方法适用于不需要程序控制的所有ActiveX控件。(4)右击该控件,选择“属性”或“Properties RemoteDataCtl Object”命令,打开该控件的属性对话框(参看图9.35)。(5)在“Control(控件)”页面中,从“DataSource”的下拉列表中选择所需要的数据源名“Database Example For VC+”。(6)在“SQL”编辑框中键入SQL语句“SELECT*FROM score ORDER BY studentno”是检索学生课程成绩表score的所有记录,并按学号排序。如图。,9.4数据库相关的ActiveX控件,(7)将RemoteData控件属性对话框切换到All页面,单击CursorDriver选项,在右侧的组合框中将其属性选择“1-ODBC cursor”。如图。该控件在这里是用于ODBC的联接,因此必须使用ODBC的游标驱动程序(CursorDriver)才能使其联接成功。,9.4数据库相关的ActiveX控件,添加并设置DBGrid控件(1)打开Ex_ODBC表单资源IDD_EX_ODBC_FORM。(2)在表单资源中右击鼠标,选择“Insert Active Control”命令,找到要添加的DBGrid控件,如图。单击确定按钮。,9.4数据库相关的ActiveX控件,(3)调整添加的DBGrid控件的大小和位置,打开该控件的属性对话框,将数据源(DataRource)设置为RemoteData控件IDC_REMOTEDATACTL1,如图。,9.4数据库相关的ActiveX控件,(4)在对话框编辑器的控件布局栏上,单击测试工具按钮(),如图。按ESC键结束测试。(5)编译运行并测试。大多数情况下,常把RemoteData控件的“显示(Visible)”属性设为不选中,以使DBGrid控件操作的界面看起来更专业一点。,