VC下的ADO编程入门
- 格式:doc
- 大小:45.00 KB
- 文档页数:6
VC++-ADOCOM组件创建Excel服务失败问题描述这个问题我印象中我两年前就遇到了,当时我做了⼀个控制台程序,读写EXCEL。
写好了,⼀执⾏就出现这个报错,也找不到什么问题,后来问了我的开发⽼师苏⼯。
他⼀语就点破了问题,COM没初始化!CoInitialize(NULL);就这么⼀句代码没加。
今天,时隔多年,我今天在开发⼀个MFC的程序,默认状态执⾏程序,初始化弹出对话框,在点OK。
可以正常读写EXCEL,但是当把OK的函数加到初始化界⾯那⾥,就报错这个问题了。
我还是找了半天没找到问题,后来还是问了开发⽼师苏⼯,他点醒我的。
这个问题还是两年前遗留下来的问题,当时我发现问题后,并没有把初始化的代码加到我封装好的SDK中,所以导致我今天继续⽤以前的SDK就出现了当年的问题。
现在要写个博客记录下这个问题,免得以后再次遇到⼜不知道。
问题演⽰解决后演⽰在我⾃⼰封装的SDK⾥,加了⼀个初始化COM的函数// 初始化Excel OLEBOOL ExcelApi::InitExcel(){// 初始化COM库CoInitialize(NULL);// 初始化Excelif (!ExcelApp.CreateDispatch("Excel.Application")){AfxMessageBox("创建Excel服务失败!");}ExcelApp.put_DisplayAlerts(FALSE); // 屏蔽警告return TRUE;}每次打开EXCEL前。
先调⼀下初始化。
Caesar卢尚宇2021年2⽉22⽇。
收稿日期226作者简介张秋波(3—),男,年毕业于西南交通大学地理信息系统专业,助理工程师。
文章编号:167227479(2010)0120016204浅谈利用VC ++对数据库的开发张秋波(中铁工程设计咨询集团有限公司济南设计院,山东济南 250022)D iscu ssi on on D evelopm en t of Da ta B a s e with VC ++Zhang Q iubo 摘 要 简要介绍了在VC ++610中使用ADO 进行客户端数据库编程的基本步骤,给出了一种在V isual C ++下封装ADO 访问数据库类的方法。
以S QL 中自带数据库North w ind 中的Catrgories 表为例,介绍其基本操作的实现过程。
关键词 VC ++ A DO 数据库中图分类号:P209 文献标识码:B1 开发环境的建立使用AppW izard 来创建MF C 工程(选择工程→新建→工程菜单,这时弹出创建向导对话框(如图1)),工程命名为“张秋波”。
图1 工程菜单在Step1中选择D 基本对话框然后单击完成。
(1)在主对话框中设置其I D :I DD_MY_D I A LOG,在工具的控制面板上选择List Contr ol 主对话框中拖出一个方框,点击右键选择Pr opertie s,设置其I D:I D C _L I ST,并利用C lassW izard (类向导)设置membe r va ri 2able na m e (变量名)为“m _list ”并添加相应的函数OnDblclkL ist 、OnR click L ist 。
然后利用工具的控制面板中的B utt on 创建四个按钮,标题分别为:添加、修改、删除、查询,I D 分别为:I DC_BUTTON_ADD 、I DC_BUT 2T ON _ED I T 、I DC _BUTT ON _D E L 、I D C _BUTTO N _SEARCH,并添加相应函数:OnB uttonAdd 、OnB utt on 2Del 、OnB uttonEdit 、OnButt onSearch 。
VC中用ADO和DataGrid控件显示和更新数据库中的数据分类:VC编程2010-07-06 15:58 1157人阅读评论(0) 收藏举报VC中用ADO和DataGrid控件显示和更新数据库中数据。
以VC6.0为例1、新建一对话框在资源视图中新建一个对话框,将对话框调整到适当大小,双击对话框创建对话框类。
2、往对话框上添加DataGrid控件在VC6中点击 Project->add to project->components and controls。
在弹出的对话框中双击Registered ActiveX Controls 在弹出的控件列表中选择Microsoft DataGrid Control 6.0(SP6)(OLEDB),点击insert,接下来的每一部都点确认按钮(ok按钮)。
我们发现在工具箱中多了一个DataGrid 控件的图标。
拖动该图标到对话框中,并且调整大小,设置属性为AllowAddNew、AllowDelete、AllowUpdate、ColumnHeaders、Enabled。
在DataCrid上右击用ClassWizard给对话框添加一个DataGrid变量m_dataGrid。
3、添加代码在对话框头文件中添加如下代码#import "C://program files//common files//system//ado//msado15.dll" no_namespace rename ("EOF", "adoEOF") 在对话框头文件的对话框类中添加如下代码_ConnectionPtr pConnection;//数据库连接指针_RecordsetPtr m_pRecordSet;//数据集指针重载对话框OnInitDialog()函数,在其中添加如下代码pConnection.CreateInstance("ADODB.Connection");///创建Connection对象CoInitialize(NULL); //初始化Com组件 pConnection.CreateInstance(__uuidof(Connection)); //Connection用于与数据库服务器的链接CString conStr; //数据库连接字符串conStr.Format(_T("Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=BookStoreDB;Data Source=MTeacher"));//注:此为ADO连接MS SQL数据库的一种方式,如果不是MS SQL数据库则连接方式不同/******************连接数据库********************/try{pConnection->ConnectionTimeout = 5; //设置连接时间pConnection->Open(_bstr_t(conStr),"","",adModeUnknown); //连接SQL SERVER}catch(_com_error e) //捕捉异常{//AfxMessageBox(e.ErrorMessage());return -5;}//创建数据集//把下列代码放入按钮控件对应的函数比如OnButton()UpdateData(true);m_pRecordSet.CreateInstance("ADODB.Recordset");m_pRecordSet->CursorLocation= adUseClient;CString cmdStr;cmdStr="select * from sourcingTbl where bookname='";cmdStr+=m_bookname;cmdStr+=_T("'");try{m_pRecordSet->Open(_variant_t(cmdStr),_variant_t((IDispatch *)pConnection,true),adOpenKeyset, adLockOptimistic, adCmdUnknown);}catch (CException e){CString emsg;e.GetErrorMessage((LPTSTR)&emsg,1);AfxMessageBox(emsg);return false;}m_dataGrid.SetRefDataSource(NULL);m_dataGrid.SetRefDataSource((LPUNKNOWN)m_pRecordSet); m_dataGrid.Refresh();CoUninitialize();//现在DataGrid控件便具有添加、删除、修改数据的功能了。
收稿日期:2001-09-28 作者简介:邹海,博士研究生,目前主要从事计算机软件的开发和研究工作.文章编号:1001-9081(2002)3-0091-02MFC 中实现ADO 对多种数据类型动态记录集的绑定邹 海1,2,向 南2(1.中国矿业大学信息与电气工程学院,江苏徐州221008;2.水利部南京水利水文自动化研究所,江苏南京210008)摘 要:在MFC 中用DAO 进行本地数据库记录集绑定,极大地提高了数据的访问的效率,但在访问远程数据库方面却显笨拙。
ADO 作为一种通用数据访问对象模型,已成为数据访问的一种趋势。
文中结合实际开发经验,详细地阐述了在MFC 中如何使用ADO 数据对象模型,来实现远程数据访问中由多种数据类型所构成的动态记录集的绑定。
关键词:ADO 数据类型;动态记录集;数据绑定中图分类号:TP311.12 文献标识码:A ADO (Active Data Objects )作为近年来Windows 应用程序开发中令人激动的变革之一,它提供了访问O LE DB 的应用程序编程接口(API )。
ADO 不仅集成了数据访问对象(DAO )和远程数据对象(RDO )两者的优点———轻量级客户端远程数据库访问,而且提供了对不是存储在传统关系数据中的数据的访问(如文件系统、工作表、电子邮件仓库等),成为M icros oft 通用数据访问(UDA )战略的核心技术。
ADO 从本质上来说是一个面向对象的接口,它是对访问O LE DB 数据源接口的封装。
C ++语言虽然支持对底层O LE DB 接口的直接调用,但大大增加了开发人员的复杂程度和开发周期。
在MFC 中用ADO 代替O LE DB 接口不仅可以减轻编码的工作量,而且可简化应用程序中使用O LE DB 获取数据的复杂程度。
但遗憾的是,M icros oft 当初设计ADO 的基本目的是用于VB 和VBScript 客户程序,因而几乎所有的ADO 文档都是为VB 程序员写的。
VC连接ACCESS数据库的代码2007-02-07 21:17:51#include "stdafx.h"#include <iostream.h>#import "c:\program files\common files\system\ado\msado15.dll" \no_namespace rename ("EOF", "adoEOF")int main(){//使用ADO连接数据库...//---------------------------------------------------------------------------------_ConnectionPtr m_pConnection;CoInitialize(NULL);m_pConnection.CreateInstance(__uuidof(Connection));// 在ADO操作中建议语句中要常用try...catch()来捕获错误信息,// 因为它有时会经常出现一些想不到的错误。
try{// 打开本地Access库db1.mdbm_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db1.mdb","","",adMode Unknown);}catch(_com_error e){cout<<"数据库连接失败,确认数据库db1.mdb是否在当前路径下!"<<endl;return FALSE;}//-------------------------------------------------------------------------------------//建立数据集//-------------------------------------------------------------------------------------_RecordsetPtr m_pR ecordset;m_pR ecordset.CreateInstance(__uuidof(Recordset));// 在ADO操作中建议语句中要常用try...catch()来捕获错误信息,// 因为它有时会经常出现一些意想不到的错误。
在我们使用MFC ADO数据库访问技术的时候经常要使用Micrisoft ADO Data Control6.0和Micrisoft DataGrid控件,但是我们会发现我们的vc6.0中点击插入ActiveX控件,如下图所示,并没有Micrisoft ADO Data Control6.0这个控件那么我们该怎么办呢?其实,可以这样解决。
1.查看电脑上是否有如下两个文件:MSDATGRD.OCX和MSADODC.OCX文件
32位系统在 C:\Windows\System32目录下查看;
64位系统在 C:\Windows\SysWOW64目录下查看。
如果目录下没有这两个文件,那么就需要下载,链接如下:
MSADODC.OCX下载
MSDATGRD.OCX下载
下载好之后,将下载的文件根据系统位数放入相应的目录下。
2.我们需要以管理员身份打开命令提示符,进行控件的注册
进入到我们文件保存的目录:
64位进入 C:\Windows\SysWOW64(不会操作的看文档最后,有介绍)然后输入regsvr32 MSADODC.OCX 回车
就可以得到如下图所示的结果
32位进入 C:\Windows\System32
然后输入regsvr32 MSADODC.OCX 回车
这样我们的控件就注册好了,再次插入ActiveX控件就可以看到我们的Micrisoft ADO Data Control6.0这个控件了。
最后呢,有些朋友可能不会在命令行窗口进行操作,这里简单介绍几种:
cd .. 回到当前目录的上一级目录cd 目录A 进入目录A
d:进入D盘
注意:输入这些命令后都是要按回车键才会执行。
VC下的ADO编程入门基本流程:(1)初始化COM库,引入ADO库定义文件(2)用Connection对象连接数据库(3)利用建立好的连接,通过Connection、Command对象执行SQL命令,或利用Record set对象取得结果记录集进行查询、处理。
(4)使用完毕后关闭连接释放对象。
具体实现步骤及说明:1.使用AfxOleInit()来初始化COM库BOOL CADOTest1App::InitInstance(){AfxOleInit();......2.用#import指令引入ADO类型库在stdafx.h中加入如下语句:#import "c:\program files\common files\system\ado\msado 15.dll" no_namespace rename("EOF","adoEOF")其最终作用同#include类似,编译的时候系统会为我们生成msado15.tlh,ado15.tli两个C++头文件来定义ADO库。
几点说明:(1) 您的环境中msado15.dll不一定在这个目录下,请按实际情况修改(2) 在编译的时候肯能会出现如下警告,对此微软在MSDN中作了说明,并建议我们不要理会这个警告。
msado15.tlh(405) : warning C4146: unary minus operator applied to unsigned type, result still unsigned3.创建Connection对象并连接数据库首先我们需要添加一个指向Connection对象的指针:_ConnectionPtr m_pConnection;下面的代码演示了如何创建Connection对象实例及如何连接数据库并进行异常捕捉。
BOOL CADOTest1Dlg::OnInitDialog(){CDialog::OnInitDialog();HRESULT hr;try{hr = m_pConnection.CreateInstance("ADODB.Connection");///创建Connection对象if(SUCCEEDED(hr)){hr = m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.md b","","",adModeUnknown);///连接数据库///上面一句中连接字串中的Provider是针对ACCESS2000环境的,对于ACCESS97,需要改为:Provider=Microsoft.Jet.OLEDB.3.51;}}catch(_com_error e)///捕捉异常{CString errormessage;errormessage.Format("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage()); AfxMessageBox(errormessage);///显示错误信息}在这段代码中我们是通过Connection对象的Open方法来进行连接数据库的,下面是该方法的原型HRESULT Connection15::Open ( _bstr_t ConnectionString, _bstr_t UserID, _bstr_t P assword, long Options )ConnectionString为连接字串,UserID是用户名, Password是登陆密码,Options是连接选项,用于指定Connection对象对数据的更新许可权,Options可以是如下几个常量:adModeUnknown:缺省。
当前的许可权未设置adModeRead:只读adModeWrite:只写adModeReadWrite:可以读写adModeShareDenyRead:阻止其它Connection对象以读权限打开连接adModeShareDenyWrite:阻止其它Connection对象以写权限打开连接adModeShareExclusive:阻止其它Connection对象以读写权限打开连接adModeShareDenyNone:阻止其它Connection对象以任何权限打开连接我们给出一些常用的连接方式供大家参考:(1)通过JET数据库引擎对ACCESS2000数据库的连接m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\test.mdb"," ","",adModeUnknown);(2)通过DSN数据源对任何支持ODBC的数据库进行连接:m_pConnection->Open("Data Source=adotest;UID=sa;PWD=;","","",adModeUnknown);(3)不通过DSN对SQL SERVER数据库进行连接:m_pConnection->Open("driver={SQL Server};Server=127.0.0.1;DATABASE=vckbase;UI D=sa;PWD=139","","",adModeUnknown);其中Server是SQL服务器的名称,DATABASE是库的名称(4) 不通过DNS对MYSQL进行连接m_pConnection->Open("Driver={MySQL ODBC 3.51 Driver};Server=127.0.0.1;Databas e=busi_process_db;Uid=root;Pwd=root;Port=3306;Option=131072;Stmt=;","","",adModeU nknown);Connection对象除Open方法外还有许多方法,我们先介绍Connection对象中两个有用的属性ConnectionTimeOut与StateConnectionTimeOut用来设置连接的超时时间,需要在Open之前调用,例如:m_pConnection->ConnectionTimeout = 5;///设置超时时间为5秒m_pConnection->Open("Data Source=adotest;","","",adModeUnknown);State属性指明当前Connection对象的状态,0表示关闭,1表示已经打开,我们可以通过读取这个属性来作相应的处理,例如:if(m_pConnection->State)m_pConnection->Close(); ///如果已经打开了连接则关闭它4.执行SQL命令并取得结果记录集定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset"); SQL命令的执行可以采用多种形式:(1)利用Connection对象的Execute方法执行SQL命令Execute方法的原型如下所示:_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * Records Affected, long Options ) 其中CommandText是命令字串,通常是SQL命令。
参数Reco rdsAffected是操作完成后所影响的行数, 参数Options表示CommandText中内容的类型,Options可以取如下值之一:adCmdText:表明CommandText是文本命令adCmdTable:表明CommandText是一个表名adCmdProc:表明CommandText是一个存储过程adCmdUnknown:未知Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
_variant_t RecordsAffected;///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthdaym_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",&RecordsAffected,adCmdText);///往表格里面添加记录m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) VALUES (1, ''Washington'',25,''1970/1/1'')",&RecordsAffected,adCmdText);///将所有记录old字段的值加一m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adC mdText);///执行SQL统计命令得到包含记录条数的记录集m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&Re cordsAffected,adCmdText);_variant_t vIndex = (long)0;_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入v Count变量m_pRecordset->Close();///关闭记录集CString message;message.Format("共有%d条记录",vCount.lVal);AfxMessageBox(message);///显示当前记录条数(2)利用Command对象来执行SQL命令_CommandPtr m_pCommand;m_pCommand.CreateInstance("mand");_variant_t vNULL;vNULL.vt = VT_ERROR;vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它m_pCommand->CommandText = "SELECT * FROM users";///命令字串m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。