QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3581|回复: 1
打印 上一主题 下一主题

[转帖]在Visual C++中用ADO进行数据库编程(上)

[复制链接]
字体大小: 正常 放大
god        

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:50 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
1. 生成应用程序框架并初始化OLE/COM库环境 $ k6 O5 ^  f* N! f1 \( h+ v( k

( j4 z, ?% i2 z1 _- _  创建一个标准的MFC AppWizard(exe)应用程序,然后在使用ADO数据库的InitInstance函数中初始化OLE/COM库(因为ADO库是一个COM DLL库)。* r  l$ [4 P- i+ y) }; [
本例为: ' \8 ^8 m' t# [4 B

) H1 @! m+ d5 u2 o; U BOOL CAdotestDlg::OnInitDialog()
. |- f: k( a# A5 F- z {: G. K8 q( L" Z& W/ E# z: ?1 G
       ::CoInitialize(NULL); //初始化OLE/COM库环境 2 }& K2 M, A1 H9 C9 H
}
. p  E6 A( U- T! D7 H# B6 q; G/ t* u9 l+ r" \- g' a& ?; U- h
  程序最后要调用 ::CoUninitialize();//释放程序占用的COM 资源。  F) ^- `5 W8 A4 k9 |) M/ ~3 g" R
3 ~: Y  p5 Y$ ~1 l8 h2 w
  另外:
$ [8 V  y( M' T8 O1 W/ k6 |7 D: ?, z0 z1 m3 ^7 V' f9 S
m_pRecordset->Close(); 注意!!!不要多次关闭!!!!!!!!!!!!
2 k+ i5 ?2 e' Y. \. p/ S/ jm_pConnection->Close();. O* \0 p3 O8 ]6 ~4 O
m_pRecordset = NULL;& W6 X9 F% z; v) g) t& e! y1 p( R
m_pConnection = NULL; , d' a& i/ @/ |/ G/ h, `5 _7 T9 H
  2. 引入ADO库文件
9 [7 o5 Y) ?6 E
+ E2 g7 f( E: T& F4 p4 a  使用ADO前必须在工程的stdafx.h文件最后用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下:
# u/ M5 ]5 v$ ]4 M: \6 A: L$ k#import "C:\Program Files\common files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF")
- ?& z5 O: [1 e$ @& s+ |  ADO类的定义是作为一种资源存储在ADO DLL(msado15.dll)中,在其内部称为类型库。类型库描述了自治接口,以及C++使用的COM vtable接口。当使用#import指令时,在运行时Visual C++需要从ADO DLL中读取这个类型库,并以此创建一组C++头文件。这些头文件具有.tli 和.tlh扩展名,读者可以在项目的目录下找到这两个文件。在C++程序代码中调用的ADO类要在这些文件中定义。
0 Q, W7 l+ U7 z* _9 p6 Q+ g0 P   程序的第三行指示ADO对象不使用名称空间。在有些应用程序中,由于应用程序中的对象与ADO中的对象之间可能会出现命名冲突,所以有必要使用名称空间。如果要使用名称空间,则可把第三行程序修改为: rename_namespace("AdoNS")。第四行代码将ADO中的EOF(文件结束)更名为adoEOF,以避免与定义了自己的EOF的其他库冲突。
- t8 E; a  D! U, U0 o4 G$ `' a: W6 k
  3.利用智能指针进行数据库操作 6 A9 b, J2 c( l/ d% s8 K

% S  E) X( _# `: H  在CaboutDlg头文件中定义两个ADO智能指针类实例,并在对话框中加入一个ListCtrl。5 W: k% b# ]; m5 i: c3 S

# G2 O( R* u& M8 h& j) Lclass CAdotestDlg : public CDialog* l% ^* f' f: a* X
{
1 C5 w! F/ n: z# b* g$ F. S    _ConnectionPtr m_pConnection;
' k  f, Q- G9 S* \3 Z2 j    _RecordsetPtr m_pRecordset;) c4 U# z3 q( P# _* B  w& F- i
   ClistCtrl m_List;
! x& `' F4 }* P9 w" Y    ......
& x1 q1 P* f2 ?  x, S- v: p}     ; ~* G: J- ^& t/ W, ]- y% @
9 t3 V1 U  n3 ~1 V
  ADO库包含三个智能指针:_ConnectionPtr、_CommandPtr和_RecordsetPtr。
" T$ P0 v/ `; S7 p+ u2 F4 U
8 }0 A3 @$ E% ^8 V4 e  _ConnectionPtr通常被用来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。7 R6 H% ?& u9 f( g( p+ s
  _CommandPtr返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时,可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。  _RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定、游标控制等。
( K& P& q- h' ]+ Z1 a2 n* J$ L. b
' V2 V# C" m7 _  在使用ADO程序的事件响应中OnButton1加入以下代码: - u0 a6 h7 H8 ?. {# w0 u

% c4 w% O$ B9 @3 o0 avoid CAdotestDlg::OnButton1() . ~) M* [% ^$ i3 T& Z
{0 s2 x( P- Z( g' z& X
m_List.ResetContent();
) ~) k0 ^1 p& N. l. I) [. a" k# Pm_pConnection.CreateInstance(_uuidof(Connection)); //初始化Connection指针8 a* n* m  H3 s* G) l2 _
m_pRecordset.CreateInstance(_uuidof(Recordset));//初始化Recordset指针
& L6 S% O  M) ~3 ]) m; ?try4 Y5 y/ L7 o/ f+ g( |4 w' a1 `0 \
{
! {/ ^! Q% D. a- R0 Z m_pConnection->Open("DSN=ADOTest","","",0); //连接叫作ADOTest的ODBC数据源
# b! ?; h9 e( o  {4 i //注意:这是连接不需要用户ID或密码的open 函数/ k4 X$ G/ D. b4 B. t% P- j
// 否则形式为 ->Open("DSN=test;uid=sa;pwd=123;","","",0); * f& ]7 R8 h; F! Y/ e6 ^% a$ h5 ]7 z
7 C/ @" O5 H$ I( c; I: k
// 执行SQL语句得到一个记录集把其指针赋值给m_pRecordset
( p- x$ w) v& d CString strSql="select * from middle";
1 V& O2 y6 I! S& G2 _ BSTR bstrSQL = strSql.AllocSysString();   `: w: N5 V+ w" O
m_pRecordset->Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText);
& m! h/ i! {# t. K8 n* a //adOpenDynamic:动态 adLockOptimistic乐观封锁法 adCmdText:文本查询语句
4 x0 `! g& z6 O3 s, k+ R; a while(!m_pRecordset->adoEOF)//遍历所有记录
9 O; [9 p" E! q; V( I0 k; y% E& n {
/ z0 T5 x6 T9 a/ d( h! m/ \0 K; y) w0 _  //取纪录字段值方式之一" D7 q5 H; V6 M2 T
  _variant_t Thevalue; //VARIANT数据类型  C3 l5 M% U8 v5 o  H
  Thevalue = m_pRecordset->GetCollect("BIG_NAME");//得到字段BIG_NAME的值
* h$ h* s' r! `6 R' c4 s  if(Thevalue.vt!=VT_NULL)$ a; }( @6 }4 t; Z, p& l  v  }# B
   m_List.AddString((char*)_bstr_t(Thevalue));
# s6 Y$ g: q6 H3 f0 H1 U- V  //将该值加入到列表控件中: x* Y3 v3 y4 k) L, }5 S

+ z+ ~& A0 ]% ?& t  //取纪录字段值方式之二
9 f+ K4 l; _- K2 G$ f0 K! O  // _bstr_t Thevalue1=m_pRecordset->Fields->GetItem("BIG_NAME")->value;# h) i1 J( c+ s; C6 q
  // CString temp=Thevalue1.copy();
* }6 d2 s( N" k) m8 [  // m_List.AddString(temp);* P3 _1 _' Y2 O" O; O; t
  //数据类型转换8 F1 p" l+ n: ^2 y4 Z
  _variant_t vUsername,vBirthday,vID,vOld;( I8 x6 v( n# d4 K+ u
  TRACE("id:%d,姓名:%s,年龄:%d,生日:%s\r\n",9 ^5 V9 n. L& R2 j
  vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday);
  e. w2 |' q3 |
8 {1 C1 ~9 ^( s9 W- q9 P  m_pRecordset->MoveNext();//转到下一条纪录
1 I5 }6 W# M- v% S& M0 o3 f! W }
' P" I' o9 k6 b- |1 ` m_pRecordset->Close();6 [, \$ f% o4 H8 V7 Y! t& b8 L
m_pConnection->Close();; L$ N0 I4 S; V' k. X
}
/ F& K/ z. u  V. z& |/ L# @catch (_com_error e)//异常处理7 w, m  X7 b0 S' _
{& U/ |9 u$ e+ q0 c0 K6 G
AfxMessageBox(e.ErrorMessage());. J. Z9 [: O' j4 _+ L2 W; W
}
; F$ }0 c! V; A* T) I0 Gm_pRecordset->Close(); //注意!!!不要多次关闭!!!!否则会出错
" f3 i0 |: v# A' s% p$ cm_pConnection->Close();
9 N" D* x) U. r2 j/ t  o9 n. Gm_pRecordset = NULL;
6 ~9 g" W, y, G) N* ^m_pConnection = NULL;
, h& @; Y$ P! m. _, \5 y}
" f# m4 p6 B1 ]& ^
# h: n. F7 L  }9 C  程序中通过_variant_t和_bstr_t转换COM对象和C++类型的数据, _variant_t类封装了OLE自治VARIANT数据类型。在C++中使用_variant_t类要比直接使用VARIANT数据类型容易得多。
0 X0 }8 S; Y' J9 v
' L/ V6 L1 z0 \/ m  好,编译后该程序就能运行了,但记住运行前要创建一个叫ADOTest的ODBC数据源。该程序将把表middle中的BIG_NAME字段值显示在列表控件中。
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
如果我没给你翅膀,你要学会用理想去飞翔!!!
chenlk        

0

主题

2

听众

26

积分

升级  22.11%

该用户从未签到

新人进步奖

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-9-2 11:05 , Processed in 0.428714 second(s), 58 queries .

回顶部