C++ ADO Oracle简述 笔记

有待补充

ADO全称 ActiveX Data Object. 

ActiveX是基于Com技术的。

以下图说明:

ADO是微软高度封装的一个基于OLE DB/ODBC 访问各种关系型数据库/非关系型数据库./其他类型文件等。

ADO通过已有的ODBC程序访问各种数据库,理论上只要数据库开发商有提供ODBC驱动程序就可以被ADO进行I/O操作。

最近学习如何使用ADO 访问Oracle的知识,做个学习笔记。方便以后再次参考

1 ADO库的引入:

ADO库以msado*.dll 命名,以下我已Win7 距离,其他系统暂不了解是否相同.

ADO库所在目录是 : C:\Program Files\Common Files\System\ado\ ,WIN7 ADO库名是: msado15.dll

引入使用 #import 关键字, 在使用的地方或stdafx.h 中包含。

#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF") // 引入时声明没有命名空间,并重命名eof避免编译时引发的报错

2 COM初始化:

ado是基于com技术的,所以在使用之前要初始化com库, 需要头文件 <comdef.h>

有两种情况的初始化:

2.1 MFC

在MFC环境下初始化可以使用函数 AfxOleInit()

2.2 WIN32

在非MFC环境下可以使用 CoInitialize()/UnCoInitialize() 进行【初始化/卸载】com环境

3 ADO 有3个智能指针:

1 _ConnectionPtr  //指针一般用于连接数据库,也可以用于数据查询,该指针可以进行事务操作【BeginTrans,CommitTrans,RollbackTrans】

2 _CommandPtr //指针用于执行数据库操作【CRUD】,对于有结果集的可以用_RecordsetPtr 指针对象接收结果集

3 _RecordsetPtr  //指针指向一个结果集,可以对结果集进行各种操作。

Mcrosoft 对于数据库的连接不强制要求某个指针是专用,事实上以上三个指针都支持直接发起对数据库的连接及操作。并不需要提前连接到数据库

PS:所有的数据库操作都基于以上三个指针。

指针对象的初始化:

 1 //用到两个函数 FAILED / SUCCEEDED 用于判断返回值
 2 
 3 HRESULT hr;
 4 //创建实例的两种方式:
 5 // #1
 6 _ConnectionPtr m_Connection;
 7 _CommandPtr m_Command;
 8 _RecordsetPtr m_Recordset;
 9 
10 hr = m_Connection.CreateInstance(__uuidof(Connection));
11 if(FAILED(hr))
12     return false;
13 
14 hr = m_Command.CreateInstance(__uuidof(Command));
15 if(FAILED(hr))
16     return false;
17 
18 hr = m_Recordset.CreateInstance(__uuidof(Recordset));
19 if(FAILED(hr))
20     return false;
21 
22 // #2
23 _ConnectionPtr m_Connection(__uuidof(Connection));
24 _CommandPtr m_Command(__uuidof(Command));
25 _RecordsetPtr m_Recordset(__uuidof(Recordset));
26 
27 hr = m_Connection.CreateInstance(__uuidof(Connection));
28 if(FAILED(hr))
29     return false;
30 
31 hr = m_Command.CreateInstance(__uuidof(Command));
32 if(FAILED(hr))
33     return false;
34 
35 hr = m_Recordset.CreateInstance(__uuidof(Recordset));
36 if(FAILED(hr))
37     return false;

4 连接数据库

智能指针初始化后,可以进行连接到数据库的操作

hr = m_Connection.Open("数据源""用户名","密码",flag);
/* 
数据源可以使用DSN ,也可以使用not dsn方式。
这里使用非DSN的方式:
指定连接串的格式: "Provider=OraOLEDB.Oracle.1;Data Source=数据库所在主机的全局服务名;"
Provider 指定数据库的类型
后面2个参数一个是指向连接数据库的用户名,一个是指向连接数据库的密码,
参数4 是连接的标志位,默认可以-1,或者 adModeUnknow. 已未知的方式打开
*/

hr = m_conn->Open("Provider=OraOLEDB.Oracle.1;Data Source=mes;","xxxxx","xxxxx",adModeUnknown);
    if(FAILED(hr))
        return FALSE;

5 关闭数据库连接

 1 if(m_Connection->state) 2 m_Connection->Close(); 3 m_Connection = NULL; 

6 数据库查询

m_Command->ActiveConnection = m_Connection; // 将已建立的连接直接赋予command对象,避免重复连接。

m_Command->CommandText = "select * from tableName"; //指定查询的sql
m_Command->CommandType = adCmdText; // 指定命令类型
adCmdText 指定是文本命令
adCmdTable 指定是一个表明
adCmdProc 指定是一个存储过程

m_Recordset = m_Command->Execute(NULL,NULL,adCmdText); // 执行sql,如果有结果集返回 m_Recordset  接收。

//遍历结果集

_variant_t val;

while(m_Recordset ->adoEOF)
{
//取结果集字段值的两种方式:
// 1
    val = m_Recordset->GetCollet("name");
    val = m_Recordset->GetCollet(long(index)); //以下标的方式访问
// 2 val = m_Recordset->get_Collect("name");
  val = m_Recordset->get_Collect(long(index)); printf(
"%s \n",(LPCSTR)val); //ADO的类型和C++基本类型不相同,需要转换 m_Recordset ->MoveNext(); //移动到下一行记录 }

添加

m_Recordset->AddNew(); //调用 AddNew 增加一行新数据

m_Recordset->PutCollect(); // 调用 PutCollect 给每一个字段赋予数据

PutCollect->Update(); // 确定提交数据

删除

1 m_Recordset->MoveFirst(); //移动到第一条记录
2 m_Recordset->Move(index); //移动到指定的位置
3 
4 m_Recordset->Delete(adAffectCurrent); //删除当前记录
5 
6 m_Recordset->Update(); //提交操作

调用存储过程:

 1 m_Command->ActiveConnection = m_Connection; 2 m_Command->CommandText = "Proc1"; 3 m_Command->Execute(NULL,NULL,adCmdStoredProc); 

遍历所有表名:

 1 _RecordsetPtr pset = m_Connection->OpenSchema(adSchemaTables);
 2 
 3 while(pset0->adoEOF)
 4 {
 5      _bstr_t strTblNname = pset->Fields->GetItem("TABLE_NAME")->Value;
 6      _bstr_t strTblType = pset->Fields->GetItem("TABLE_TYPE")->Value;
 7     
 8     pset->MoveNext();
 9 }
10 
11 pset->Close();

附录:

1、_variant_t (1)、一般传给这3个指针的值都不是MFC直接支持的数据类型,而要用 _variant_t 转换一下        

_variant_t(XX) 可以把大多数类型的变量转换成适合的类型传入    

(2) 、 _variant_t  var;      

_variant_t  ->  long:  (long)var;        

_variant_t  ->  CString:  CString  strValue  =  (LPCSTR)_bstr_t(var);        

CString  ->  _variant_t:  _variant_t( strSql);

2 、 BSTR 宽字符串与 CString 相互转换       

BSTR  bstr;        

CString  strSql;        

CString  ->  BSTR:  bstr  =  strSql.AllocSysString();        

BSTR  ->  CString:  strSql  =  (LPCSTR)bstr;   

3 、 _bstr_t 与 CString 相互转换       

_bstr_t  bstr;       

CString  strSql;        

CString  ->  _bstr_t:  bstr  =  (_bstr_t)strSql;       

_bstr_t  ->  CString:  strSql  =  (LPCSTR)bstr;   

4 、关于时间       

Access: 表示时间的字符串 #2004-4-5#       

Sql: 表示时间的字符串 ''2004-4-5''        

DateField( 时间字段 )        

select *  from  my_table where  DateField  >  #2004-4-10#       

try        

{            

m_pCommand->CommandText  =  "INSERT  INTO  tTest( age)  VALUES('23f2')  ";            

m_pRecordset  =  m_pCommand->Execute(NULL,NULL,  adCmdText);         

}        

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

{            

CString  errormessage;            

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

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

}

猜你喜欢

转载自www.cnblogs.com/emjx/p/11285830.html
ADO