1、VC+程序设计第15讲,数据库编程1,2004/12/07,8.1 数据库基本概念,8.1.1 数据库可以做什么 信息检索 从互联网获取的信息很多是从数据库中得到 数据共享 公司的各个分部之间的数据共享 决策支持 为个人或者公司决策提供信息支持,8.1 数据库基本概念,8.1.2 数据、数据库、DBMS和SQL 数据 对客观事物特征的一种抽象的、符号化的表示 数据具有以下特征 数据有“类型”和“值” 数据受到数据类型和取值范围的约束,8.1 数据库基本概念,8.1.2 数据、数据库、DBMS和SQL 数据库 存放数据的仓库,由若干数据库对象组成 数据库对象 数据表存放数据的文件,以表格的形式出
2、现视图虚拟数据表,由查询数据库表产生 存储过程完成特定的功能而汇集在一起的一组SQL 程序语句,经编译后存储在数据库中的SQL 程序,8.1 数据库基本概念,8.1.2 数据、数据库、DBMS和SQL DBMS-数据库管理系统 用于管理数据库的计算机软件 数据管理 用户管理 安全控制 并发控制 每一种数据库都有自己的DBMS Access SQL Server Oracle,8.1 数据库基本概念,8.1.2 数据、数据库、DBMS和SQL DBMS-数据库管理系统,8.1 数据库基本概念,8.1.2 数据、数据库、DBMS和SQL SQL-结构化查询语言 用于查询和操作数据库的语言 SQL需
3、要DBMS支持 简单的SQL语法 select从指定表中取出指定的列的数据 SELECT select_list INTO new_table FROM table_source WHERE search_condition GROUP BY group_by_expression HAVING search_condition ORDER BY order_expression ASC | DESC ,8.1 数据库基本概念,8.1.2 数据、数据库、DBMS和SQL SQL-结构化查询语言 简单的SQL语法 select示例 Select * from contact Select nam
4、e,email from contact Select * from contact where group_str=friend Select * from contact order by name,8.1 数据库基本概念,8.1.2 数据、数据库、DBMS和SQL SQL-结构化查询语言 简单的SQL语法 Insert into在表中插入新行(记录) INSERT INTO table_name VALUES (value1, value2,) 指定所有字段的值INSERT INTO table_name (column1, column2,.)VALUES (value1, value
5、2,) 指定部分字段的值,8.1 数据库基本概念,8.1.2 数据、数据库、DBMS和SQL SQL-结构化查询语言 简单的SQL语法 Insert into示例 Insert into contact Values(jack,2234567,,friend)Insert into contact(name,email) Values(jack,),8.1 数据库基本概念,8.1.2 数据、数据库、DBMS和SQL SQL-结构化查询语言 简单的SQL语法 Update更新表中原有数据 UPDATE table_name SET column_name = new_value WHERE co
6、lumn_name = some_value Update 示例 Update contact set email= where name=tom,8.1 数据库基本概念,8.1.2 数据、数据库、DBMS和SQL SQL-结构化查询语言 简单的SQL语法 Delete删除表中的数据 DELETE FROM table_name WHERE column_name = some_value Delete 示例 Delete from contact where name=tom 更详细的资料可以查看以下链接 http:/ 数据库基本概念,8.1.3 ODBC(Open Database Con
7、nectivity) 基本概念 开放式数据库互连 数据库组成部分 提供对数据库访问的标准API 支持SQL语句 工作原理 不依赖于任何DBMS,由ODBC驱动完成操作 不同的数据库厂商的ODBC驱动是不一样的 以统一的ODBC API处理异构数据库,8.1 数据库基本概念,8.1.3 ODBC 组成部件 应用程序 ODBC管理器 驱动程序管理器 数据源 ODBC API ODBC驱动程序,8.1 数据库基本概念,8.1.3 ODBC 组成部件之间的关系,数据源名,应用程序,ODBC管理器,ODBC API/SQL,驱动程序管理器,ODBC驱动程序,数据源,应用层,ODBC层,数据层,8.1 数
8、据库基本概念,8.1.3 ODBC 使用ODBC访问数据库的基本流程 注册数据源 在程序中使用数据源 使用ODBC API或者SQL访问数据库 由驱动程序管理器将API传递给对应的驱动程序 驱动程序执行相应操作返回数据,8.1 数据库基本概念,8.1.3 ODBC 注册数据源示例step1,8.1 数据库基本概念,8.1.3 ODBC 注册数据源示例step2,8.1 数据库基本概念,8.1.3 ODBC 注册数据源示例step3,8.1 数据库基本概念,8.1.3 ODBC 注册数据源示例step4,8.1 数据库基本概念,8.1.3 ODBC 注册数据源示例step5,8.1 数据库基本概
9、念,8.1.3 ODBC 注册数据源示例查看已创建的数据源,8.1 数据库基本概念,8.1.4 VC的多种数据库访问机制 ODBC DAOCOM技术 OLE DBOLE技术 ADO RDO,8.2 基于ODBC的MFC类,8.2.1 用于ODBC方式的MFC类概述 CDatabase 建立与数据源的连接 CRecordset 操作完成后返回的数据集合 CRecordView 和记录集关联的表单视图,用于和用户交互 CFieldExchange 支持记录字段数据交互,8.2 基于ODBC的MFC类,8.2.2 CDatabase 建立连接 virtual BOOL Open( LPCTSTR l
10、pszDSN, BOOL bExclusive = FALSE, BOOL bReadOnly = FALSE, LPCTSTR lpszConnect = “ODBC;”, BOOL bUseCursorLib = TRUE ); throw( CDBException, CMemoryException ); lpszDSN-数据源名称 bExclusive-是否独占数据源 bReadOnly-是否只读 lpszConnect-连接字符串,包含连接信息,8.2 基于ODBC的MFC类,8.2.2 CDatabase 建立连接 建立连接示例断开连接 virtual void Close( )
11、;,CDatabase m_dbContact; m_dbContact.Open( _T( “mydb“ ), FALSE, FALSE,_T( “ODBC; “ ) / .,m_dbContact.Close();,8.2 基于ODBC的MFC类,8.2.2 CDatabase 测试连接 BOOL IsOpen( ) const;获得连接字符串 const CString,BOOL bOpened=m_dbContact.IsOpen();,Cstring strConn=m_dbContact.GetConnect();,Cstring strDBName=m_dbContact. Ge
12、tDatabaseName();,8.2 基于ODBC的MFC类,8.2.3 CRecordset 记录集的相关概念 记录集的类型 动态集(dynasets)和快照(snapshots) 共同点:在建立记录集后就有确定的数据 对数据更新的反映能力(下表),E修改记录,A增加记录,D删除记录,S自己,O其他用户,8.2 基于ODBC的MFC类,8.2.3 CRecordset 记录集的相关概念 字段数据成员和数据交换 从CRecordset派生一个子类得到需要的记录集 记录中的每一个字段对应子类中的一个数据成员 RFX机制用于在程序和记录之间交换数据 记录集的功能 滚动记录 更新记录:修改、删除
13、和添加 记录排序和记录过滤,8.2 基于ODBC的MFC类,8.2.3 CRecordset 记录集建立和关闭 记录集是某一个查询的结果 记录集的建立 构造记录集对象 CRecordset( CDatabase* pDatabase = NULL); pDatabase指向CDatabase对象,用来获取数据源 pDatabase为空则自动创建一个CDatabase对象 如果CDatabase对象没有和数据源连接,CRecordset对象的Open函数中会建立连接,连接数据源所用的字符串,由GetDefaultConnect提供,8.2 基于ODBC的MFC类,8.2.3 CRecordset
14、 记录集建立和关闭 记录集的建立 调用Open函数查询数据源中的记录并建立记录集 virtual BOOL Open( UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE, LPCTSTR lpszSQL = NULL, DWORD dwOptions = none ); throw(CDBException, CMemoryException);,8.2 基于ODBC的MFC类,8.2.3 CRecordset 记录集建立和关闭 记录集的建立 Open函数的参数说明 nOpenType记录集的类型 lpszSQLSQL语句或者表名,为空时使用GetDeafult
15、SQL函数的返回值 dwOption选项 需要重载的几个成员函数 virtual CString GetDefaultConnect( );,return _T(“ODBC;DSN=mydb“);,8.2 基于ODBC的MFC类,8.2.3 CRecordset 记录集建立和关闭 记录集的建立 需要重载的几个成员函数 virtual CString GetDefaultSQL( );用于更新数据的函数 virtual BOOL Requery( );,CString CDBTestSet:GetDefaultSQL() return _T(“contact“); ,8.2 基于ODBC的MFC
16、类,8.2.3 CRecordset 记录集建立和关闭 记录集的建立 过滤记录和记录排序 CRecordset:m_strFilter用于过滤记录,/ Example for CRecordset:m_strFilter CContactSet rsContactSet( NULL );/ 设置过滤字符串 rsContactSet.m_strFilter = “group_str= friend”; / 执行过滤操作 rsContactSet.Open( CRecordset:snapshot, “Contact“ );,8.2 基于ODBC的MFC类,8.2.3 CRecordset 记录集
17、建立和关闭 记录集的建立 过滤记录和记录排序 CRecordset:m_strSort用于记录排序,/ Example for CRecordset:m_strSort CContactSet rsContactSet( NULL ); / 设置排序字符串 rsContactSet.m_strSort = “name“; / 执行排序操作 rsContactSet.Open( CRecordset:snapshot, “Contact” );,8.2 基于ODBC的MFC类,8.2.3 CRecordset 记录集建立和关闭 关闭记录集 virtual void Close( ); 关闭记录集
18、后可以再次调用Open建立新的记录集,CContactSet rsContactSet( NULL ); if( ! rsContactSet.Open( ) ) return FALSE; / 使用记录集. / 关闭记录集 rsContactSet.Close( );,8.2 基于ODBC的MFC类,8.2.3 CRecordset 滚动记录 记录集滚动函数 CRecordset:MoveNext 滚动到下一条记录 CRecordset:MovePrev 滚动到上一条记录 CRecordset:MoveFirst 滚动到第一条记录 CRecordset:MoveLast 滚动到最后一条记录,
19、8.2 基于ODBC的MFC类,8.2.3 CRecordset 滚动记录 记录集滚动函数 CRecodeset: Move( long nRows, WORD wFetchType = SQL_FETCH_RELATIVE) nRows,滚动的记录数,正值向记录集末尾滚动,负值向记录集起点滚动 nRows为0,刷新当前记录,结束编辑模式或添加模式并恢复原来的值 CRecordset:SetAbsolutePosition( long nRows ) nRows,定位记录的序号,从1开始,8.2 基于ODBC的MFC类,8.2.3 CRecordset 滚动记录 记录集边界判断函数 CReco
20、rdset:IsBOF 是否在第一条记录之前 CRecordset:IsEOF 是否在最后一条记录之后,8.2 基于ODBC的MFC类,/ 打开记录集; 第一条记录是当前记录 CContactSet rsContactSet( NULL ); rsContactSet.Open( ); if(rsContactSet.IsBOF( ) ) return; / 空记录集 / 滚动到记录集末尾,未选中任何记录 while ( ! rsContactSet.IsEOF( ) ) rsContactSet.MoveNext( );/ 滚动到最后一条记录 rsContactSet.MoveLast( )
21、; / 滚到到记录集开始,未选中任何记录 while( ! rsContactSet.IsBOF( ) ) rsContactSet.MovePrev( ); / 滚动到第一条记录 rsContactSet.MoveFirst( );,8.2 基于ODBC的MFC类,8.2.3 CRecordset 修改、添加和删除记录 修改记录 调用CRecordset:Edit进入编辑模式 将当前字段数据成员值保存到缓冲区 若再次调用Edit则恢复保存的数据,且仍处于编辑模式 若调用Move(0)可退出编辑模式,并恢复字段数据成员的值 设置字段数据成员的新值 调用CRecordset:Update完成编辑
22、操作 Update将变化后的记录写入数据源并退出编辑模式,8.2 基于ODBC的MFC类,8.2.3 CRecordset 修改、添加和删除记录 修改记录 修改记 录示例,/ 进入编辑模式 rsContactSet.Edit( ); / 修改字段数据成员 rsContactSet.m_name = tom; rsContactSet.m_email = ““; /完成编辑操作 if( ! rsContactSet.Update( ) ) / 更新失败时的处理 ,8.2 基于ODBC的MFC类,8.2.3 CRecordset 修改、添加和删除记录 添加记录 调用CRecordset:AddNe
23、w进入添加模式 将当前字段数据成员值保存到缓冲区 若再次调用AddNew则恢复保存的数据,且仍处于添加模式 若调用Move(0)可退出添加模式,并恢复字段数据成员的值 设置字段数据成员的值 调用CRecordset:Update完成添加操作 Update将新的记录写入数据源并退出添加模式,8.2 基于ODBC的MFC类,8.2.3 CRecordset 修改、添加和删除记录 添加记录 添加记 录示例,/ 进入添加模式 rsContactSet.AddNew( ); / 设置字段数据成员 rsContactSet.m_name = Jack; rsContactSet.m_email = ““;
24、 /完成添加操作 if( ! rsContactSet.Update( ) ) / 添加失败时的处理 ,8.2 基于ODBC的MFC类,8.2.3 CRecordset 修改、添加和删除记录 删除记录 调用CRecordset:Delete当前删除记录 将当前字段数据成员清空 在记录集和数据源中给当前记录设置删除标志 必须调用一次Move函数才能真正删除当前记录 删除记录示例,CContactSet rsContactSet(m_dbContact);rsContactSet.Open( ); / 删除当前记录 rsContactSet.Delete( ); rsContactSet.Move
25、Next();,8.2 基于ODBC的MFC类,8.2.4 CRecordView 类层次结构CRecordView的功能 显示当前记录 滚动记录 修改、添加和删除记录,8.2 基于ODBC的MFC类,8.2.4 CRecordView 典型的CRecordView示例,8.2 基于ODBC的MFC类,8.2.4 CRecordView CRecordView的数据交换机制 CRecordView使用DDX数据交换机制在控件和记录集成员之间交换数据 数据交换通过DoDataExchange函数完成,void CDBTestView:DoDataExchange(CDataExchange* pDX) CRecordView:DoDataExchange(pDX);/AFX_DATA_MAP(CDBTestView)DDX_FieldText(pDX, IDC_EDIT_ID, m_pSet-m_id, m_pSet);/AFX_DATA_MAP ,8.2 基于ODBC的MFC类,8.2.4 CRecordView DDX和RFX数据交换机制,数据字段,ID,Name,1,Jack,DDX,m_id,m_name,id,name,RFX,CRecordView,CRecordSet,数据源中的表,控件,数据成员,