不要问我WHY。懒人的VC++ADO开发简单指南

来源:互联网 发布:网络化妆课程 编辑:程序博客网 时间:2024/05/17 02:08

转自:

Shane的BLOG


                                Shane·Xia(就是本人)

首先申明:本文仅面向初学者,非常初的那种,有任何关于为什么的问题,请勿询问本人,浩瀚如烟的MSDN就是你的去处。我们这里仅解决如何做的问题,目标是让大家能够让自己的程序立刻跑起来,能够做一些自己想要的简单操作。

流程:

 

不要问我WHY。懒人的VC++ADO开发简单指南

传说中的瀑布模型,可以让你看上去更专业一点

(当然也仅仅是看上去,因为诸葛先生说:“过时了”)

准备工作

我们要引入ADO类型库:

#import "c:\Program Files\Common Files\System\ADO\msado15.dll" no_namespace rename("EOF", "EndOfFile")

注:”EndOfFile”可以更换为其他字符串,在后面的程序看到”EndOfFile”更换为你自己定义的字符串即可。

为了使用Execute方法,请包含icrsint.h

#include "icrsint.h"

 

开始编程工作:

初始化COM库

CoInitialize(NULL);

AfxOleInit();

注:CoInitialize(NULL);用于非MFC环境下初始化COM库

    AfxOleInit();用于MFC环境下初始化COM库

有说法2个都必须有,但我在实践中仅用CoInitialize(NULL)未发生问题,共同使用也未发生问题。暂时将2者都应用了。

HRESULT hr; //用于表示错误代码

if FAILED(CoInitialize(NULL))  // COM 初始化调用

{

CoUninitialize();

AfxOleInit();

hr = E_UNEXPECTED;

}

建立数据库连接

用Connection对象连接数据库:

添加一个指向Connection对象的指针:

_ConnectionPtr m_pConnection;

HRESULT hr; //用于表示错误代码

hr = m_pConnection.CreateInstance("ADODB.Connection");//创建Connection对象实例

住:无论是Connection对象还是Recordset对象都必须使用CreateInstance方法创建对象实例,否则其后续操作无法完成。

连接数据库:

m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Test.mdb","","", adModeUnknown); //Access2000

m_pConnection->Open("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=test.accdb”,"","", adModeUnknown);//Access2007

m_pConnection->Open("Provider=SQLOLEDB.1;Server=iim-xia; Database=TestDB; uid=sa; pwd=这是密码不告诉你; ","","",adModeUnknown);//SQLSever

注:其中Server是数据库服务器名,Database是数据库名,uid是用于登录该数据库的用户名,pwd是该用户的密码,错误代码error  #3149是用户名密码错误。

 

下面是一段用于连接数据库的程序:用try和catch块来捕捉错误以防止程序崩溃。

CoInitialize(NULL);

AfxOleInit();//

_ConnectionPtr m_pConnection;//建立Connection对象的指针;

HRESULT hr; //用于表示错误代码

try

{

       hr = m_pConnection.CreateInstance("ADODB.Connection");//创建Connection对象

       if(SUCCEEDED(hr))

       {

       hr=m_pConnection->Open("Provider=SQLOLEDB.1;Server=iim-xia;Database=TestDB; uid=sa;pwd=这是密码不告诉你;","","",adModeUnknown); //创建面向SQL server的连接

       }

}

catch(_com_error e)///捕捉异常

{

       CString errormessage;

       errormessage.Format("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage());

       AfxMessageBox(errormessage);///显示错误信息

}

以上是建立数据链接的过程,针对不同的数据库,替换红字标注的部分。

 

获取数据

首先建立数据集,我们的一切操作以数据集(Recordset)为基础:

我们需要一个指向Recordset的指针:

_RecordsetPtr m_pRecordset;

同Connection对象一样,必须实例化:

m_pRecordset.CreateInstance("ADODB.Recordset");

使用Open方法来使用SQL语言对数据库操作:

m_pRecordset->Open("SELECT ID,X,Y,SpeedGroup,TenNum FROM TestList " ,

 _variant_t((IDispatch*)m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);

这是一条select语句:从表TestList中选择列名为“ID”、“X”、“Y”、“SpeedGrooup”、“TenNum”放入m_pRecordset(数据集对象指针)。

 

这时我们的数据集里就有ID、X、Y、SpeedGroup、TenNum这些值。他们的排列顺序来自于你的Select语句,而非数据库里的表里的列的位置。你也可以用通配符“*”(SELECT * FROM TestList)来选择表TestList中所有的列。

 

为了您的程序安全,避免程序崩溃,请“踹”(try) it。如下:

HRESULT hr; //用于表示错误代码

try

{

       hr = m_pRecordset.CreateInstance("ADODB.Recordset");//创建Recordset对象

       if(SUCCEEDED(hr))

       {

          hr=m_pRecordset->Open("SELECT ID,X,Y,SpeedGroup,TenNum FROM TestList",_variant_t((IDispatch*)m_pConnection,true),adOpenStatic, adLockOptimistic , adCmdText); //创建数据集。

       }

}

catch(_com_error e)///捕捉异常

{

       CString errormessage;

       errormessage.Format("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage());

       AfxMessageBox(errormessage);///显示错误信息

}

 

下面是如何将数据集中的数据取出(这里只是一般性的数据:int、long、char之类):

先来个CString C_DataS,还需要一个_variant_t  Y,(传说中具有超强能力的数据类型)然后我们继续“踹”(try)

CString C_DataS; _variant_t  Y;

try

{

       while(! m_pRecordset-> EndOfFile)

       {

              Y=m_pRecordset->GetCollect("ID");//获取列名为ID的列的数据

              if(Y.vt!=VT_NULL)

              {

                  C_DataS.Format("%d",Y.lVal);//将Y的值放入CString中

                  float i=atof(C_DataS);//将CString的值转为float类型

                      cout<<i<<endl;

              }

               m_pRecordset->MoveNext();

        }

}

catch(_com_error e)///捕捉异常

{

       CString errormessage;

       errormessage.Format("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage());

       AfxMessageBox(errormessage);///显示错误信息

}

注:CString的类型转换去网上查询。

try

{

       m_pRecordset->MoveFirst();

       //m_pRecordset->Delete(adAffectCurrent);//删除当前行

       m_pRecordset->AddNew();

       int IDDD=40400;

       m_pRecordset->PutCollect("ID",_variant_t((int)IDDD));

       m_pRecordset->PutCollect("X",_variant_t((double)1));

       m_pRecordset->PutCollect("Y",_variant_t((double)1));

       m_pRecordset->PutCollect("SpeedGroup",_variant_t((int)1));

       m_pRecordset->PutCollect("TenNum",_variant_t((int)1));

       m_pRecordset->Update();

}

catch(_com_error e)///捕捉异常

{

       CString errormessage;

       errormessage.Format("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage());

       AfxMessageBox(errormessage);///显示错误信息

}

上面的一“踹”是用来添加一行数据的。注释掉的那一行是用于删除操作。

m_pRecordset->Update();执行后,才真正的修改了数据库。

注:以上的一“踹”不能在使用Execute方法建立的数据集里“踹”。(我不知道是不是我自己的问题)

 

更简单的方法,使用Connection->Execute方法来建立数据集,方法如下:

m_pRecordset = m_pConnection->Execute("SELECT * FROM TentacleCoordinate", &RecordsAffected , adCmdText);

别忘了定义:

_variant_t RecordsAffected;

 

其它的对数据库的操作:

 

这些都是基于SQL语言的,Execute方法。

创建表:

m_pConnection->Execute("CREATE TABLE TestList(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",&RecordsAffected,adCmdText);

 

插入值:

m_pConnection->Execute("INSERT INTO TestList(ID,username,old,birthday) VALUES (1, 'Washington',25,'1970/1/1')",&RecordsAffected,adCmdText);

 

别忘了关上它:

饭前便后要洗手,洗手别忘关龙头:

if(m_pRecordset->State)

{

       AfxMessageBox("关闭记录集");

       m_pRecordset->Close();///关闭记录集

}

if(m_pConnection->State)

{

       AfxMessageBox("关闭连接");

       m_pConnection->Close();

}



全文放在魔方上了:word版提取文件连接 http://pickup.mofile.com/6413769572832015  

                  提取码:6413769572832015 

                  PDF版取文件连接 http://pickup.mofile.com/4343336894601838    

                  提取码:4343336894601838

自从上一篇开始好久没有继续把剩下的继续写出来了,我是懒人吗,因该可以理解的(这里无耻一把先)

        上一次的文章里没有写如何修改数据库中某一行的值这里给出一try:

try

{

       m_pRecordset->Move(400,_variant_t((long)adBookmarkFirst));

       m_pRecordset->PutCollect(_variant_t("Y"),_variant_t((long)45));

       m_pRecordset->Update();

}

catch(_com_error e)///捕捉异常

{

       CString errormessage;

       errormessage.Format("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage());

       AfxMessageBox(errormessage);///显示错误信息

}

这一“踹”用于修改某一行的值。Move是移动recordset指针到从首行以后的第400行。

注:第一行为0。所以这句话是移动到了第401行处。

PutCollect就是修改列名为“Y”的当前行的值。

 

 

下面便开始建立一个最简单地数据库应用程序,简单到连界面都没有的(Win32控制台程序)。

建立一个工程,如图

不要问我Why,懒人的VC++ADO开发简单指南(二)

 

文件->新建->项目

不要问我Why,懒人的VC++ADO开发简单指南(二)

选择Visual C++项目->Win32->Win32控制台项目

 

不要问我Why,懒人的VC++ADO开发简单指南(二)

 

在此页面选择应用程序设置活页->钩上MFC,选择完成。

钩上MFC可以让我们使用一些MFC特性的东西。

不要问我Why,懒人的VC++ADO开发简单指南(二)

在解决方案资源管理器中可以看到:

源文件:stdafx.cpp、TESTDB.cpp

头文件:stdafx.h、Resource.h、TESTDB.h

 

我们在stdafx.h中添加:

#import "c:\Program Files\Common Files\System\ADO\msado15.dll" no_namespace rename("EOF", "EndOfFile")

请放在#include <afx.h>之后。

在添加用于使用Execute方法的头文件#include "icrsint.h"

 

然后便可在TESTDB.cpp添加自己的数据库处理代码:

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])

{

         int nRetCode = 0;

 

         // 初始化 MFC 并在失败时显示错误

         if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))

         {

                   // TODO: 更改错误代码以符合您的需要

                   _tprintf(_T("致命错误: MFC 初始化失败\n"));

                   nRetCode = 1;

         }

         else

         {

                   // TODO: 在此处为应用程序的行为编写代码。

         }

 

         return nRetCode;

}

以上为自动生成代码。

我们在else大括号中添加代码:

// TESTDB.cpp : 定义控制台应用程序的入口点。

//

 

#include "stdafx.h"

#include "TESTDB.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

 

 

// 唯一的应用程序对象

 

CWinApp theApp;

 

using namespace std;

 

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])

{

       int nRetCode = 0;

 

       // 初始化 MFC 并在失败时显示错误

       if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))

       {

              // TODO: 更改错误代码以符合您的需要

              _tprintf(_T("致命错误: MFC 初始化失败\n"));

              nRetCode = 1;

       }

       else

       {

              // TODO: 在此处为应用程序的行为编写代码

              HRESULT hr; //用于表示错误代码

              if FAILED(CoInitialize(NULL))  // COM 初始化调用

              {

                     CoUninitialize();

                     AfxOleInit();

                     hr = E_UNEXPECTED;

              }

              //以上为初始化COM库

              _ConnectionPtr m_pConnection;//建立Connection对象的指针;

              try

              {

                     hr = m_pConnection.CreateInstance("ADODB.Connection");//创建Connection对象

                     if(SUCCEEDED(hr))

                     {    

                           hr=m_pConnection->Open("Provider=SQLOLEDB.1;Server=iim-xia;Database=TestDB; uid=sa;pwd=这是密码不告诉你;","","",adModeUnknown);); //创建面向SQL server的连接

                     }

              }

              catch(_com_error e)///捕捉异常

              {

                     CString errormessage;

                     errormessage.Format("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage());

                     AfxMessageBox(errormessage);///显示错误信息

              }

              //以上建立数据库连接(面向SQL Server的)

              _RecordsetPtr m_pRecordset;

              try

              {

                     hr = m_pRecordset.CreateInstance("ADODB.Recordset");//创建Recordset对象

                     if(SUCCEEDED(hr))

                     {

                            hr=m_pRecordset->Open("SELECT ID,X,Y,SpeedGroup,TenNum FROM TentacleCoordinate",_variant_t((IDispatch*)m_pConnection,true),adOpenStatic, adLockOptimistic , adCmdText); //创建数据集。

                     }

              }

              catch(_com_error e)///捕捉异常

              {

                     CString errormessage;

                     errormessage.Format("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage());

                     AfxMessageBox(errormessage);///显示错误信息

              }

              //以上建立数据集(面向SQL Server的)

              CString C_DataS; _variant_t  Y;

              try

              {

                     while(! m_pRecordset-> EndOfFile)

                     {

                            Y=m_pRecordset->GetCollect("ID");//获取列名为ID的列的数据

                            if(Y.vt!=VT_NULL)

                            {

                                   C_DataS.Format("%d",Y.lVal);//将Y的值放入CString中

                                   float i=atof(C_DataS);//将CString的值转为float类型

                                   cout<<i<<endl;

                            }

                            m_pRecordset->MoveNext();

                     }

              }

              catch(_com_error e)///捕捉异常

              {

                     CString errormessage;

                     errormessage.Format("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage());

                     AfxMessageBox(errormessage);///显示错误信息

              }

              //以上为获取并显示列名为“ID”的数据

              try

              {

                     m_pRecordset->MoveFirst();

                     //m_pRecordset->Delete(adAffectCurrent);//删除当前行

                     m_pRecordset->AddNew();

                     int IDDD=40400;

                     m_pRecordset->PutCollect("ID",_variant_t((int)IDDD));

                     m_pRecordset->PutCollect("X",_variant_t((double)1));

                     m_pRecordset->PutCollect("Y",_variant_t((double)1));

                     m_pRecordset->PutCollect("SpeedGroup",_variant_t((int)1));

                     m_pRecordset->PutCollect("TenNum",_variant_t((int)1));

                     m_pRecordset->Update();

              }

              catch(_com_error e)///捕捉异常

              {

                     CString errormessage;

                     errormessage.Format("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage());

                     AfxMessageBox(errormessage);///显示错误信息

              }

              //以上为添加一行数据

              if(m_pRecordset->State)

              {

                     AfxMessageBox("关闭记录集");

                     m_pRecordset->Close();///关闭记录集

              }

              if(m_pConnection->State)

              {

                     AfxMessageBox("关闭连接");

                     m_pConnection->Close();

              }

              //关闭数据集和连接

       }

 

       return nRetCode;

}

以上程序经调试通过。

 

常用数据的转换:

从数据库中读取数据需要对数据类型进行转换:

使用_variant_t得变量来从数据库中获取所需数据,定义如下:

_variant_t DATA;

然后使用 DATA.lavl的方法来将DATA中所存放的数据转换为我们所需的数据(lavl 转换为长整型 long)

DATA. dblVal,转换为双精度类型double。

DATA. fltVal,转换为浮点型 float。(注我在SQL Server2005中使用浮点数,但是必须用双精度才能正确读出,若是读为浮点数则数值不正确)。


原创粉丝点击