Visual C++数据库编程快速入门.doc_第1页
Visual C++数据库编程快速入门.doc_第2页
Visual C++数据库编程快速入门.doc_第3页
Visual C++数据库编程快速入门.doc_第4页
Visual C++数据库编程快速入门.doc_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Visual C+数据库编程快速入门odbc(open database connectivity,开放数据库互连)是微软公司开放服务结构(wosa,windows open services architecture)中有关数据库的一个组成部分,它建立了一组规范,并提供了一组对数据库访问的标准api(应用程序编程接口)。这些api利用sql来完成其大部分任务。odbc本身也提供了对sql语言的支持,用户可以直接将sql语句送给odbc。一个基于odbc的应用程序对数据库的操作不依赖任何dbms,不直接与dbms打交道,所有的数据库操作由对应的dbms的odbc驱动程序完成。也就是说,不论是foxpro、access还是oracle数据库,均可用odbc api进行访问。由此可见,odbc的最大优点是能以统一的方式处理所有的数据库。一个完整的odbc由下列几个部件组成:应用程序(application)。 odbc管理器(administrator)。该程序位于windows 95控制面板(control panel)的32位odbc内,其主要任务是管理安装的odbc驱动程序和管理数据源。驱动程序管理器(driver manager)。驱动程序管理器包含在odbc32.dll中,对用户是透明的。其任务是管理odbc驱动程序,是odbc中最重要的部件。odbc api。 odbc 驱动程序。是一些dll,提供了odbc和数据库之间的接口。 数据源。数据源包含了数据库位置和数据库类型等信息,实际上是一种数据连接的抽象。各部件之间的关系如图下图所示:应用程序要访问一个数据库,首先必须用odbc管理器注册一个数据源,管理器根据数据源提供的数据库位置、数据库类型及odbc驱动程序等信息,建立起odbc与具体数据库的联系。这样,只要应用程序将数据源名提供给odbc,odbc就能建立起与相应数据库的连接。在odbc中,odbc api不能直接访问数据库,必须通过驱动程序管理器与数据库交换信息。驱动程序管理器负责将应用程序对odbc api的调用传递给正确的驱动程序,而驱动程序在执行完相应的操作后,将结果通过驱动程序管理器返回给应用程序。在访问odbc数据源时需要odbc驱动程序的支持。用visual c+ 5.0安装程序可以安装sql server、 access、 paradox、 dbase、 foxpro、 excel、 oracle 和microsoft text等驱动程序在缺省情况下,vc5.0只会安装sql server、 access、 foxpro和dbase的驱动程序如果用户需要安装别的驱动程序,则需要重新运行vc 5.0的安装程序并选择所需的驱动程序。 1 ado是微软整个com战略体系中的一个组成部分活动数据对象(ado)是一组由微软提供的com组件。 ado建立在微软所提倡的com体系结构之上,它的所有接口都是自动化接口,因此在c+、visualbasic、delphi等支持com的开发语言中通过接口都可以访问到ado。ado通过使用ole db这一新技术实现了以相同方式可以访问关系数据库、文本文件、非关系数据库、索引服务器和活跃目录服务等的数据,扩大了应用程序中可使用的数据源范围,从而成为微软整个com战略体系中访问数据源组件的首选,是odbc的替代产品。2 ado对象模型组成 与微软的其它数据访问模型dao和rdo相比,ado对象模型非常精炼,仅由三个主要对象connection、command、recordset和几个辅助对象组成,其相互关系如图所示。connection对象提供ole db数据源和对话对象之间的关联,它通过用户名称和口令来处理用户身份的鉴别,并提供事务处理的支持;它还提供执行方法,从而简化数据源的连接和数据检索的进程。command对象封装了数据源可以解释的命令,该命令可以是sql命令、存储过程或底层数据源可以理解的任何内容。record set用于表示从数据源中返回的表格数据,它封装了记录集合的导航、记录更新、记录删除和新记录的添加等方法,还提供了批量更新记录的能力。其它辅助对象则分别提供封装ado错误、封装命令参数和封装记录集合的列。3 ado的特点分析(1)由于封装了许多底层工作,使用ado与使用odbc几乎是一样方便。(2) ado不仅具有odbc的主要功能,而且ado适用的数据源的范围要大的多。(3)在定义ado记录集变量和数据库表字段绑定类时,要求记录集的字段变量、状态变量与数据库表字段的个数、顺序必须相同。这一点比在fmc中使用odbc要复杂一些。但在数据库字段与ado记录集字段变量绑定的宏中,ado 提供的数据类型要远多于fmc中的rfx(如日期时间类型,在odbc中只能转换为cstring类型)。 (4)ado允许同一connection实例下有多个record set实例。 (5)ado允许进行批更新(使用的update batch方法),这样将大大减轻网络负担,提高数据库处理效率。 4 ado在visual c+中的使用 close(); (12) 调用counitialize释放com资源 :couninitialize(); 5 结论 作为odbc的替代产品,ado确实有其过人之处。由于ado数据源几乎覆盖了目前常见的数据源类型,对于odbc所不支持的数据源,ado无疑是唯一的选择。而ado的批更新功能,更是网络环境下大数据量更新应用的重要因素。由于ado缺乏大量的第三方厂商的支持,使得ado目前远不如odbc普及,但其面向对象的特性将使ado具有比较广阔的发展前景。 有很多种使用数据库的方法,对大多数数据库来说,选择c+这种产品也许并不适宜。我们知道,像dbase iv,foxpro,oracle和access这样的产品是完全以数据库管理为中心的。事实上,这些产品非常善于创建数据库管理器,以至于它们确实并不善于做太多其它的工作。即使要用更通用化而非更专用化的数据库产品来执行一些类型的工作,在使程序设计更容易这一方面,像visualbasic和delphi这样的rad环境也要比visual c+强很多。 你是不是对我的说法感到很奇怪?下面我就要谈一谈,在谈到使用数据库管理系统(dbms)这个话题时,用visual c+实际上可以做些什么。虽然上述其它语言使得编写成熟的包括用户界面和高速搜索能力的dbms就像孩子做游戏一样容易,但是,它们缺少visual c+可以提供的某些重要东西。你不能为使用access的数据库轻松地编写出实用程序。正像实用程序的定义所说的,实用程序应该很小并且具备可移植性access应用程序却不是这样。即使用access这样的产品创建的程序可以很小并且可以移植,你仍有其它方面的需求:底层的功能。 注:编写数据库实用程序及驱动程序时,可以选择visual c+语言。 想像一下,使用像visual basic这样的语言来与实时数据采集设备打交道的情况。在进行底层访问时,rad的保护环境常常使程序员不能进行有效的处理。当然,数据采集设备几乎不依赖于简明的连接。你打算如何把visual basic和外部的数据源连接起来呢?数据源甚至可能不了解windows,dos或类似的成熟的操作系统。 只要使用得当,很容易看到visual c+是一种不可或缺的数据库管理工具。针对大规模的应用程序,即使你仍想依赖于visual basic这样的rad语言,也请考虑一下visual c+,它创建的程序规模小、提供底层访问并能提供实时访问。事实上,你可能还没有想到,visual c+数据库应用程序的市场是很有潜力的。随着人们在旅途中越来越多地使用膝上型和掌上型电脑,这两类电脑上的数据库应用程序也变得越来越普通。你也许能够适应今天的膝上型电脑上的access应用程序,但谈到硬盘大小或内存需求时,公司里较老的膝上型电脑可能就达不到要求。运行windows ce的掌上型电脑在运行这个access应用程序时,肯定会发生故障。在这一数据库市场的新领域,visual c+提供了无价无限的工具。 web链接 谈到使用visual c+和数据库,其实你并不孤单。从一开始就有数据库专用新闻组提供有关数据库创建技巧的帮助,比如microsoft.public.access。不过,这些新闻组提供的是通用信息,对实际编写应用程序并非全都那么有用。专门针对visual c+问题的新闻组是microsoft.public.vc.database和microsoft.public.vc.mfcdatabase。如果你决定用odbc访问数据库,可能还要查看一下microsoft.public.odbc.sdk新闻组,它讨论的不仅仅是sdk。对最新技术感兴趣的程序员可以查阅microsoft.public.ado新闻组,或者microsoft.public.oledb(对象链接和嵌入数据库)新闻组,前者讨论 ado,后者讨论ado的基础技术。在microsoft.public.ado.rds有一个ado子组,它讨论远程数据访问。 既然所有的疑惑都消除了,大多数人的信心也就增强了,下面我们就介绍两种使c+访问数据库中的数据的主要方法:odbc(开放数据库互连)和ado(activex数据对象)。在本章中,将介绍这两种类型的访问方法,但我想你会发现,ado方法是针对新的程序设计情形而采用的。它克服了早期技术的诸多限制,依赖于microsoft新的底层访问方法ole-db(对象链接和嵌入数据库)。在本书的后面我们会看到,用ado和visual c+提供的各种向导来汇集数据库工程,其速度有多快。 注 odbc通常用来访问不具备ole-db特性的非microsoft数据库中的数据;16位的odbc驱动程序工作起来可能非常缓慢。 odbc素以最慢的数据访问方法而著称,但是很可惜,当ado或dao都不支持某个数据库管理器而odbc支持这个数据库管理器时,在这种特定的情形下,你仍然需要使用odbc。在大多数情况下,这意味着要从数据库厂商那里获得所需的驱动程序,虽然visual c+确实附带了一些产品的驱动程序(如果你正在使用数据库管理器的某些神秘功能,那么就需要建立自己的接口棗这并不是一件十分困难的事)。本质上讲,你总是要使用odbc来访问microsoft产品之外的其它dbms产品所创建的数据库,这些数据库并不具备ole-db功能。odbc还要求做一些额外的工作棗为ado调整visual c+中的大部分向导。 高级技巧 除了使用ado和odbc外,你还可以使用像dao(数据访问对象)这样的早期技术,该技术包含在像access这样的microsoft产品中。dao依赖于用microsoft access自动获得的microsoft jet数据库引擎。dao还是较早版的visual basic所使用的引擎(最新版的visual basic和visual c+依赖于相同的ado/ole-db组合),所以如果需要支持较早的visual basic应用程序,那么dao仍是一个不错的选择。 尽管microsoft文件声明,可以用dao访问非microsoft产品建立的数据库,但你仍会发现,在这种情况下,使用ado和odbc要好得多。这样的话,不但兼容性问题会少一些,速度也将有所提高,因为数据请求经过的接口层减少了。有一条经验要记住,dao是设计用来处理mdb文件的。 ado的一个问题是,它不支持远程通信。这是microsoft提出rdo(远程数据对象)的原因之一。这种特别技术在visual basic应用程序中的使用,要比在visual c+中的使用多得多,所以我猜想,你们中有很多人都在使用它。但是,记住rdo仍是一种生命力很强的技术,这一点很重要。ado确实具有替代rdo的远程数据服务(rds)特征。换言之,ado在一个软件包中提供了dao和rdo两种功能性。 一般情况下appwizard会在数据库应用程序中自动产生crecordset的派生类,并将派生类和某个数据源中的表联系起来也可以和视图上的子窗口联系起来。但是有时这样做会影响到程序的灵活性,这时候我们可以单独使用crecordset类。利用crecordset类我们可以执行sql语句,并可以读出结果集中数据。 首先我们需要包含头文件afxdb.h,可以将#include 添加到stdafx.h文件中。此外在使用crecordset时必须有一个又一个cdatabase对象,该对象的作用是管理数据源连接。然后可以产生一个crecordset对象,利用bool crecordset:open( uint nopentype = afx_db_use_default_type, lpctstr lpszsql = null, dword dwoptions = none )可以执行sql语句。 但执行成功后,可以调用以下的函数滚动光标,读取数据。 movefirst 移动光标到第一条记录处 movenext 移动光标到后一条记录处 moveprev 移动光标到前一条记录处 movelast 移动光标到最后一条记录处 isbof 检测光标是否在第一条记录上 iseof 检测光标是否在最后一条记录上 getfieldvalue 得到结果中数据 下面是具体代码: /* 假设cdatabase m_dbconn为成员变量假设有一个表有如下sql语句产生:create table table1(loc_id not null)*/void cyourclass:connecttodb()/连接数据库bool fok = m_dbconn.open(test);trace(connect fok=%dn,m_dbconn); void cyourclass:select()/执行select语句crecordset rec(&m_dbconn);bool fok = rec.open(crecordset:forwardonly,select loc_id from table1 order by loc_id);trace(select fok = %dn,fok);trace(返回的列数为:%dn,rec.getrowsetsize();cstring szresult;while(!rec.iseof()rec.getfieldvalue(int)0,szresult);rec.movenext();trace(fetch : %sn,szresult); 此外crecordset:getfieldvalue有很多种原型,你可以通过指定列位置或是字段名来获取数据: void getfieldvalue( lpctstr lpszname , cdbvariant& varvalue , short nfieldtype = default_field_type ); void getfieldvalue( short nindex , cdbvariant& varvalue , short nfieldtype = default_field_type ); void getfieldvalue( lpctstr lpszname , cstring& strvalue ); void getfieldvalue( short nindex , cstring& strvalue ); 如果使用cdbvariant类型变量来获取结果,你可以得到任何类型的结果。在cdbvariant:m_dwtype成员变量中记录了该变量所包含的数据类型,根据该变量的值你可以确定数据类型并引用cdbvariant对象中的相应成员变量。 要建立与数据源的连接,首先应构造一个cdatabase对象,然后再调用cdatabase的open成员函数open函数负责建立连接,其声明为 virtual bool open( lpctstr lpszdsn, bool bexclusive = false, bool breadonly = false, lpctstr lpszconnect = “odbc;”, bool busecursorlib = true ); throw( cdbexception, cmemoryexception ); 参数lpszdsn指定了数据源名(构造数据源的方法将在后面介绍),在lpszconnect参数中也可包括数据源名,此时lpszdsn必需为null,若在函数中未提供数据源名且使lpszdsn为null,则会显示一个数据源对话框,用户可以在该对话框中选择一个数据源参数bexclusive说明是否独占数据源,由于目前版本的类库还不支持独占方式,故该参数的值应该是false,这说明数据源是被共享的参数breadonly若为true则对数据源的连接是只读的参数lpszconnect指定了一个连接字符串,连接字符串中可以包括数据源名、用户帐号(id)和口令等信息,字符串中的odbc表示要连接到一个odbc数据源上参数busecursorlib若为true,则会装载光标库,否则不装载,快照需要光标库,动态集不需要光标库 若连接成功,函数返回true,若返回false,则说明用户在数据源对话框中按了cancel按钮。若函数内部出现错误,则框架会产生一个异常。 下面是一些调用open函数的例子。 cdatabase m_db; /在文档类中嵌入一个cdatabase对象 /连接到一个名为student registration的数据源 m_db.open(student registration); /在连接数据源的同时指定了用户帐号和口令 m_db.open(null,false,false,odbc;dsn=student registration;uid=zyf wd=1234); m_db.open(null); /将弹出一个数据源对话框 要从一个数据源中脱离,可调用函数close。在脱离后,可以再次调用open函数来建立一个新的连接调用isopen可判断当前是否有一个连接,调用getconnect可返回当前的连接字符串。函数的声明为 virtual void close( ); bool isopen( ) const; /返回true则表明当前有一个连接 const cstring& getconnect( ) const; cdatabase的析构函数会调用close,所以只要删除了cdatabase对象就可以与数据源脱离。 crecordview(记录视图)是cformview的派生类,它提供了一个表单视图(参见6.4.1)来显示当前记录一个典型的记录视图如图10.3所示,用户可以通过表单视图显示当前记录通过记录视图,可以修改、添加和删除数据用户一般需要创建一个crecordview的派生类并在其对应的对话框模板中加入控件 记录视图使用ddx数据交换机制在表单中的控件和记录集之间交换数据。在前面介绍的ddx都是在控件和控件父窗口的数据成员之间交换数据,而记录视图则是在控件和一个外部对象(crecordset的派生类对象)之间交换数据清单10.3显示了一个crecordview的派生类的dodataexchange函数,读者可以看出,该函数是与m_pset指针指向的记录集对象的域数据成员交换数据的,而且,交换数据的代码是classwizard自动加入的在后面的例子中,将向读者介绍用classwizard连接记录视图与记录集对象的方法 清单10.3 用来与记录集对象的域数据成员交换数据的dodataexchange函数 void csectionform: odataexchange(cdataexchange* pdx) crecordview: odataexchange(pdx); /afx_data_map(csectionform) ddx_fieldtext(pdx, idc_course, m_pset->m_courseid, m_pset); ddx_fieldtext(pdx, idc_section, m_pset->m_sectionno, m_pset); ddx_fieldtext(pdx, idc_instructor, m_pset->m_instructorid, m_pset); ddx_fieldtext(pdx, idc_room, m_pset->m_roomno, m_pset); ddx_fieldtext(pdx, idc_schedule, m_pset->m_schedule, m_pset); ddx_fieldtext(pdx, idc_capacity, m_pset->m_capacity, m_pset); /afx_data_map 作为总结,图10.4显示了mfc的odbc应用程序中的ddx和rfx数据交换img/tech/visual%20c+jc/t10_4.gif/img图10.4 ddx和rfx数据交换机制 crecordview本身提供了对下面四个命令的支持: id_record_first /滚动到记录集的第一个记录 id_record_last /滚动到记录集的最后一个记录 id_record_next /前进一个记录 id_record_prev /后退一个记录 crecordview提供了onmove成员函数处理这四个命令消息,onmove函数对用户是透明的,清单10.4列出了onmove的源代码 清单10.4 onmove函数 bool crecordview:onmove(uint nidmovecommand) crecordset* pset = ongetrecordset(); if (pset->canupdate() pset->edit(); if (!updatedata() return true;pset->update(); switch (nidmovecommand) case id_record_prev: pset->moveprev(); if (!pset->isbof() break; case id_record_first: pset->movefirst(); break; case id_record_next: pset->movenext(); if (!pset->iseof() break; if (!pset->canscroll() / clear out screen since were sitting on eof pset->setfieldnull(null); break; case id_record_last: pset->movelast(); break; default: / unexpected case value assert(false); / show results of move operation updatedata(false); return true; 在函数的开头先调用crecordset:edit进入编辑模式,接着调用updatedata将控件中的数据更新到记录集对象的域数据成员中,然后调用crecordset:update将域数据成员的值写入数据源这说明onmove在滚动记录的同时会完成对原来记录的修改 在函数的中间有一个分支语句用来处理四个不同的命令,在这个分支语句中调用了crecordset的各种用于滚动记录的成员函数,这些函数在滚动到一个新的记录时会把该记录的内容设置到域数据成员中在函数的末尾调用updatedata(false)把新的当前记录的内容设置到表单的控件中。 由此可见,onmove一来一回完成了两次表单控件和数据源的数据交换过程通过分析该函数,读者可以学会在浏览记录时如何控制ddx和dfx数据交换 对于在windows上编写数据库程序的程序员来说,activex data objects (ado) 是最常使用的技术了,通过ado可以简单的实现数据库的连接以及数据访问。但是在vc+中使用ado时,却因为是使用com的方式来调用,常常出现一些系统无法编译通过,或使用中程序非法出错的问题,在这里想大概介绍一下中调用ado的常用方法。 1、 用import导入ado 的 com 文件msado15.dll 例如: #import c:program filescommon filessystemadomsado15.dllno_namespace 2、com 使用时初始化 hresult cominit() hresult hr = s_ok; / 默认返回值if failed(coinitialize(null) / com 初始化调用couninitialize();hr = e_unexpected;return hr; 3、建立数据库连接 open(pconnstring, puserid,puserpassword,connectoption);return hr;catch(_com_error &pcomerror) / 错误处理return e_unexpected; 4执行一个sql 查询,得到数据集(recordset) execute(m_ strsql,null, adcmdtext);return ptrrs;catch(_com_error &a_pcomerror)./ 错误处理return null; 5通过数据集(recordset)得到列的名称 count;/ 循环取得列的属性和名称for(int iindex = 0 ; iindex type;return s_ok;catch(_com_error &a_pcomerror). / 错误处理return e_unexpected;catch(.). / 错误处理return e_unexpected; 6通过数据集(recordset)得到当前行记录 hresult getonerecord(_recordsetptr ptrrs,const long lnoofcolumns,_variant_t varvalue)try/ 参数变量_variant_t l_vaindex;l_vaindex.vt = vt_i2;/ 循环取得列的值for(long lindex = 0; lindex value;return s_ok;catch(_com_error &a_pcomerror). / 错误处理return e_unexpected;catch(.). / 错误处理return e_unexpected; 7出错情况下错误信息的取得 count;for(long i = 0; i description); / 错误描述/ ado 处理出错的情况下, 在connection对象里面都有记录,可以通过访问/ connection 对象取得错误编号和错误信息。 odbc(open database conectivity)即开放式数据库互联,作为windows开放性结构的一个重要部分已经为很多的windows程序员所熟悉,odbc的工作依赖于数据库制造商提供的驱动程序,使用odbc api的时候,windows的odbc管理程序,把数据库访问的请求传递给正确的驱动程序,驱动程序再使用sql语句指示dbms完成数据库访问工作,因此,odbc的存在为我们开发应用数据库程序提供了非常强大的能力和灵活性。 为了使odbc能与数据库一起工作,必须把数据库注册到odbc驱动程序管理器,这项工作可以通过定义一个dsn或数据源名字来完成。通常,我们只能手动打开系统控制面板,运行其中的odbc数据源管理器,手工配置数据源,但是这项工作对用户而言过于复杂,我们必须考虑用程序替用户完成这些配置工作。 因此许多程序员在发布自己编写的数据库软件时候都希望能有一个优秀的安装程序能够自动设置好odbc数据源,虽然现在installshield等一些优秀的安装制作软件可以帮助我们实现此类功能,但毕竟缺少灵活,程序员不能完全控制它,事实上,我们完全可以自己编写一些程序实现此类功能,实现的方法有几种,一种办法是用程序修改windows注册表,程序员可以用windows api函数增改hkey_local_machinesoftwareodbc下的odbc.ini中的键值,这种方法比较烦琐。我现在推荐一种在程序中使用odbc api的方法,程序员可以在任何时候都可以用visual c+编写的程序调用这些api函数来设置odbc数据源。 下面我用mfc写一个程序来演示如何实现这个功能: 首先,打开visual c+,在file菜单上选new,然后选定mfc appwizard(exe)类的项目,project name我们定为try,按下ok键,下一step 1屏幕中选dialog based,由于不必用到后面的选项,此时即可按下finish键,结果系统将生成一个新的项目。完成上述工作后,在左侧workspace窗口中,选择resourceview,打开try resources中的dialog资源,选择并打开idd_try_dialog对话窗口,在controls菜单窗口中点选按键图标,回到idd_try_dialog对话窗口并点击此窗口,将生成一个名叫button1的按键,选中此按键再按鼠标右键,在弹出式菜单上选properties选项,在出现的对话框中把caption项的button1值改为setup odbc,关闭此对话框,再选中此按键按鼠标右键,选择classwizard,在出现的对话窗口中,object ids选idc_button1,messages中双击bn_clicked,此时弹出add member function对话窗,member function name是onbutton1,按ok键。在member functions选项中双击onbutton1 on_idc_buttion1:bn_clicked,在出现的void ctrydlg:onbutton1()函数中用以下odbc api函数语句替换 /todo: add your control notification handler code here这条注释语句: qlconfigdatasource(null,odbc_add_sys_dsn,microsoft access driver (*.mdb)0,dsn=trydb0dbq=d:databasetry.mdb0defaultdir=d:database00); 您可以根据您不同的设置需要修改上面的语句,sqlconfigdatasource一般有以下几个许可的参数:odbc_add_dsn: 加入一个新的用户数据源,odbc_config_dsn: 修改一个存在的用户数据源,odbc_remove_dsn: 删除一个存在的用户数据源,odbc_add_sys_dsn: 增加一个新的系统数据源,odbc_config_sys_dsn: 修改一个存在的系统数据源,odbc_remove_sys_dsn: 删除一个存在的系统数据源,odbc_remove_default_dsn: 删除省缺的数据源说明部分。需要注意的是,当我们使用sqlconfigdatasource odbc api函数时必须声明包含系统的odbcinst.h头文件,所以我们再选择workspace窗口中fileview打开header files中try.h,在其中加入#include odbcinst.h,如果不加入这个头文件,系统编译时就会显示undeclared identifier错误,在完成上述步骤后,假如我们立即编译并link这个项目,会发现出现下面的错误: trydlg.obj : error lnk2001: unresolvedexternal symbol _sqlconfigdatasource16debug/try.exe : fatal error lnk1120: 1 unresolved externals 有些人可能因为找不出错误而放弃了,其实这是因为当我们使用sqlconfigdatasource 这个api函数时候必须用到odbccp32.dll,它是microsoft提供的32位odbc安装和管理的dll,如果是16位必须用到odbcinst.dll,odbccp32.dll有一个import library,所以解决的办法就是把这个odbccp32.lib加到我们的项目中,我们可以打开project系统菜单项,选add to project子菜单,在其中选files项,打开vc安装目录下的vclib目录,文件类型选library files(.lib), 选择其中odbccp32.lib后按ok键,然后重新编译即可通过,运行这个程序,将弹出对话窗,按下setup odbc按键,之后,您就可以通过控制面板的odbc数据源管理器或注册表查看运行结果,您会发现,您的数据库已经成功的注册了。 以上代码均在win98,vc6.0上编译通过,您可以灵活应用这些办法,让您编写的软件更易于安装维护和使用。 microsoft developer studio为大多数标准的数据库格式提供了32位odbc驱动器。这些标准数据格式包括有:sql server、access、paradox、dbase、foxpro、excel、oracle以及microsoft text。如果用户希望使用其他数据格式,则需要安装相应的odbc驱动器及dbms。 用户使用自己的dbms数据库管理功能生成新的数据库模式后,就可以使用odbc来登录数据源。对用户的应用程序来说,只要安装有驱动程序,就能注册很多不同的数据库。登录数据库的具体操作参见有关odbc的联机帮助。 一、mfc提供的odbc数据库类 visual c+的mfc基类库定义了几个数据库类。在利用odbc编程时,经常要使用到 cdatabase(数据库类)、crecordset(记录集类)和crecordview(可视记录集类)。 cdatabase类对象提供了对数据源的连接,通过它可以对数据源进行操作。 crecordset类对象提供了从数据源中提取出的记录集。crecordset对象通常用于两种形式:动态行集(dynasets)和快照集(snapshots)。动态行集能与其他用户所做的更改保持同步,快照集则是数据的一个静态视图。每种形式在记录集被打开时都提供一组记录,所不同的是,当在一个动态行集里滚动到一条记录时,由其他用户或应用程序中的其他记录集对该记录所做的更改会相应地显示出来。 crecordview类对象能以控件的形式显示数据库记录,这个视图是直接连到一个crecordset对象的表视图。 二、应用odbc编程 应用visual c的appwizard可以自动生成一个odbc应用程序框架,步骤是:打开file菜单的new选项,选取projects,填入工程名,选择mfc appwizard (exe),然后按appwizard的提示进行操作。 当appwizard询问是否包含数据库支持时,如果想读写数据库,那么选定database view with file support;如果想访问数据库的信息而不想写回所做的改变,那么选定database view without file support。 选好数据库支持之后,database source 按钮会被激活,选中它去调用data options对话框。在database options对话框中会显示出已向odbc注册的数据库资源,选定所要操作的数据库,如:super_es,单击ok后出现select database tables对话框,其中列举了选中的数据库包含的全部表;选择要操作的表后,单击ok。在选定了数据库和数据表之后,就可以按照惯例继续进行appwizard操作。 特别需要指出的是:在生成的应用程序框架view类(如:csuper_esview)中,包含一个指向csuper_esset对象的指针m_pset,该指针由appwizard建立,目的是在视表单和记录集之间建立联系,使得记录集中的查询结果能够很容易地在视表单上显示出来。 要使程序与数据源建立联系,需用cdatebase:openex()或cdatabase:open()函数来进行初始化。数据库对象必须在使用它构造记录集对象之前初始化。 三、实例 1.查询记录 查询记录使用crecordset:open()和crecordset:requery()成员函数。在使用crecordset类对象之前,必须使用crecordset:open()函数来获得有效的记录集。一旦已经使用过crecordset:open()函数,再次查询时就可以应用crecordset:requery()函数。 在调用crecordset:open()函数时,如果将一个已经打开的cdatabase对象指针传给crecordset类对象的m_pdatabase成员变量,则使用该数据库对象建立odbc连接;否则如果m_pdatabase为空指针,就新建一个cdatabase类对象,并使其与缺省的数据源相连,然后进行crecordset类对象的初始化。缺省数据源由getdefaultconnect()函数获得。也可以提供所需要的sql语句,并以它来调用crecordset:open()函数,例如:super_esset.open(afx_database_use_default,strsql); 如果没有指定参数,程序则使用缺省的sql语句,即对在getdefaultsql()函数中指定的sql语句进行操作: cstring csuper_esset:getdefaultsql()return _t(bsicdata,minsize); 对于getdefaultsql()函数返回的表名,对应的缺省操作是select语句,即: select *from basicdata,mainsize 在查询过程中,也可以利用crecordset的成员变量m_strfilter和m_strsort来执行条件查询和结果排序。m_strfilter为过滤字符串,存放着sql语句中where后的条件串;m_strsort为排序字符串,存放着sql语句中order by后的字符串。如: super_esset.m_strfilter=type=电动机;super_esset.m_strsort=voltage;super_esset.requery(); 对应的sql语句为: select *from basicdata,mainsizewhere type=电动机order by voltage 除了直接赋值给m_strfilter以外,还可以使用参数化。利用参数化可以更直观、更方便地完成条件查询任务。使用参数化的步骤如下: s声明参变量: cstring p1;float p2; s在构造函数中初始化参变量: p1=_t();p2=0.0f;m_nparams=2; s将参变量与对应列绑定: setfieldtype(cfi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论