关闭

ado使用方法

标签: bindingnullmicrosoftcomponentsinsertfilter
1981人阅读 评论(0) 收藏 举报
分类:

一、直接使用控件:

就是普通的OCX控件操作,简单的要命。首先选中菜单Project->Add To Project->Components And Control…,在对话框中选中Registered ActiveX Controls目录下的Microsoft ADO Data Control 6.0 (SP4) (OLEDB)然后点击Insert,把ADO控件的类文件导入到当前工程之中。此时你的控件工具条(Controls工具条)上就多了一个浅绿色的控件,把拖到你的对话框中,……(作者此处删去500字)。
需要注意的是不要忘记包含各个导入类的头文件,否则编译通不过。

二、使用ADO的智能指针:

虽然相关介绍满天飞,为了保持文章的完整,还是简单介绍一下吧!

1、引入ADO库文件,一般是在stdAfx.h文件中添加
#import <msado15.dll> no_namespace rename( "EOF", "adoEOF" )

这条语句会在工程所在目录生成msado15.tlh和msado15.tli两个文件。

2、初始化Com环境
在CMyApp::InitInstance()函数中加入:
if ( FAILED(::CoInitialize(NULL)) )
{
::AfxMessageBox( "Com Init Fail !" );
::exit(0);
}

在CMyApp::ExitInstance()函数中加入
m_pRS -> Close();
m_pRS = NULL;
m_pConn -> Close();
m_pConn = NULL:
::CoUninitialize();


3、在你的类声明文件中加入智能指针对象实例的定义,做为成员变量,
_ConnectionPtr m_pConn;
_RecordsetPtr m_pRs;

A、使用之前先初始化,

//初始化ADO成员
TESTHR( m_pConn.CreateInstance(__uuidof(Connection ) ) );
TESTHR( m_pRs.CreateInstance(__uuidof( Recordset) ) );

其中TESTHR定义如下:

void TESTHR(HRESULT x) {
    if FAILED(x)
     _com_issue_error(x);
    };

B、然后就是连接数据库,获取Recordset……用不着我多说了吧,代码如下:
//Open Connection
TESTHR( m_pConn->Open( strConn/*连接字符串*/, "", "", adConnectUnspecified ) );

//Open table
TESTHR( m_pRs->Open( SQL/*SQL查询语句*/,
_variant_t((IDispatch*)m_pConn, true),
adOpenKeyset,//adOpenForwardOnly,
adLockReadOnly,
adCmdText) );

三、常用操作

1、打开记录集:
m_pRS=m_pConn->Execute(CommandText,RecordsAffected,Options)
说明如下:
 CommandText:包含要执行的SQL语句,表名、存储过程名或特定提供者的文本;
 RecordsAffected:可选,长整型,提供者返回操作的影响的记录数目;
 Options:常量,可选,长整型,具体如下:
  adCmdText:指示提供者应将CommandText赋值为命令的文本定义
  adCmdTable:返回CommandText命名的表中的所有行
  adCmdTableDirect:与上类同,返回表的所有行
  adCmdStoredProc:应将CommandText赋值为存储过程
  adCmdUnknown:CommandText参数中的命令类型未知
  adExecuteAsync:命令应异步执行
  adFetchAsync:指示CacheSize属性指定的初始数量之后的行应异步提取。
 例:m_pRS=m_pConn->Execute(L"select * from p_users",NULL,adCmdText);

2、使用记录集
 A、读取数据
  _variant_t varValue;
  varValue=m_pRS->GetFields()->GetItem((long)i)->Value;//读取当前记录的第i+1个字段的值
  varValue=m_pRS->GetFields()->GetItem((long)i)->Name;//读取当前记录的第i+1个字段的名字
  也可根据字段名来访问该字段的值:
  varValue=m_pRS->GetCollect(L"字段名"); //读取当前记录的第i+1个字值的值
 B、更新数据
  _bstr_t bstrValue="新数据";
  m_pRS->GetFields()->GetItem((long)i)->Value=bstrValue; //更新当前记录第i+1个字段的值
  m_pRS->Update();
 C、添加数据
  if (m_pRS->Support(adAddNew)&&m_pRS->Support(adUpdate))
  {
    m_pRS->AddNew();//插入一条新记录
    m_pRS->GetFields()->GetItem((long)0)->Value=L"YP00100"; //为每个字段赋值
    m_pRS->GetFields()->GetItem((long)1)->Value=L"速效感冒胶囊";
    m_pRS->GetFields()->GetItem((long)2)->Value=L"SXGMJN";
    m_pRS->Update();//更新记录集
  }
 D、删除数据
  m_pRS->Delete(adAffectCurrent);//默认,仅删除当前记录
  m_pRS->Delete(adAffectGroup);//删除满足当前Filter属性设置的记录。

 以上操作相对麻烦,采用Connection对象的Execute方法,可能更简单些,举例如下:
 添加数据:
  CString sSql,sName,sXingBie,sStipend,sID;
  sName="张三";
  sXingBie="男";
  sStipend="2200";
  sID="5";
  sSql.Format("insert into 员工信息表 Value(%s,%s,%s,%s)",sName,sXingBie,sStipend,sID);
  m_pRS=m_pConn->Execute((_bstr_t)sSql,NULL,adCmdText);
  
  其它操作类同。

四、使用Visual C++ Extensions for ADO(以下简称ADO Extensions)操作数据表。

这东东是专为VC++程序言准备的,笔者认为使用起来很方便。可遗憾的是相关介绍少之又少,连微软的MSDN上也只是寥寥数笔,真让人摸不着头脑。所以只好根据使用经验讲讲。

要使用ADO Extensions 首先要完成以上第二种方法的所有步骤,实现ADO的智能指针调用,然后再实现一个IADORecordBinding类型的指针,用它将一个Recordset和一个定义好的类绑定到一起,这样你就可以象操作C++的类一样操作数据表了,还免去了自己处理VARIANT变量类型的诸多不便。

首先定义一个与数据表相对应的类,用于绑定,

#include <icrsint.h>//Head File Of IADORecordBinding

class CTabClass : public CADORecordBinding
{
BEGIN_ADO_BINDING(CTabClass)
//( 列序号,字段类型,缓冲区,…)
ADO_NUMERIC_ENTRY ( 1, adDecimal, m_nWID, 38/*精度*/, 0/*小数位*/, s_nWID,false)
ADO_VARIABLE_LENGTH_ENTRY2( 2, adVarChar, m_Word, sizeof(m_Word), s_Word,    TRUE)
ADO_FIXED_LENGTH_ENTRY ( 3, adSmallInt, m_nLWord,s_nLWord, TRUE)
ADO_VARIABLE_LENGTH_ENTRY2( 4, adChar, m_Attr, sizeof(m_Attr), s_Attr, TRUE)
ADO_FIXED_LENGTH_ENTRY   ( 7,adInteger,m_nType, s_nType,TRUE)
END_ADO_BINDING()

public:

//与各字段对应的变量
DECIMAL m_nWID;   
CHAR m_Word[MAX_WORD+1];
INT m_nLWord;  
INT m_nType;    
CHAR m_Attr[MAX_ATTR+1];

//以上各变量绑定后的状态
ULONG s_nWID;   
ULONG s_nLWord;
ULONG s_Word;   
ULONG s_Attr;
ULONG s_nType;  

public:

//成员函数
CTabWord()
{
InitTab();
}

void InitTab();    //初始化各成员变量的值。
};

注意,将 begin_ado_binding 和 end_ado_binding 宏之间的绑定条目用括号括起。不要在绑定条目结尾使用逗号或分号,因为这些定界符仅限在宏中使用。

ado_variable_length_binding
_entry2的参数说明如下:

  参数1:按顺序的字段号码,1为标识记录集中第一字段,2为标识记录集中第二字段,依此类推。
  参数2:储存已转换字段的变量的数据类型。
  参数3:临时的工作缓冲区,用于将字段值从 variant转换为c/c++ 变量。
  参数4:变长变量所需的字节数。
  参数5:指示字段转换是否成功。
  参数6:布尔标志。如果为 true,则表明 ado 可以更新绑定的字段。如只检查字段而不将其更改,可设置为 false。

  其中第5个参数为状态参数,它可告诉你从 recordset 字段到c或c++变量的转换是否成功以及变量的内容是否有效。该参数的两个最重要的值是adfldok(意味着转换成功)和adfldnull(意味着字段是null,即无值可供转换)。程序中要检测该参数以决定c或c++变量是否有效。例如,如果字段具有有效的行内容,状态将会是adfldok,如果移动到另一个字段为 null 的行,则状态将是 adfldnull。

这里顺便再提一句:IADORecordBinding与IRecordset是由同一个类实现的不同接口,所以当你移动的记录指针时不要忘记另一个接口的记录指针也被移动了。


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:912366次
    • 积分:10655
    • 等级:
    • 排名:第1517名
    • 原创:277篇
    • 转载:57篇
    • 译文:0篇
    • 评论:53条
    最新评论