QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:50 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
1. 生成应用程序框架并初始化OLE/COM库环境 ; x& w, C  q- q& m. e# z+ p. M1 X' l: t

) R4 k: k* M/ o) k6 }( o# }  创建一个标准的MFC AppWizard(exe)应用程序,然后在使用ADO数据库的InitInstance函数中初始化OLE/COM库(因为ADO库是一个COM DLL库)。
! c. m( |; c" m, l本例为: 0 Z( y( M: v9 a
: a+ C- I2 o5 D. E% S( ^
 BOOL CAdotestDlg::OnInitDialog()4 f3 }3 `4 s8 ?' Q% J: S$ C; n
 {
, ^0 p- }+ }; ~3 K1 |8 \       ::CoInitialize(NULL); //初始化OLE/COM库环境
1 h9 E4 M: |% T* [: b# g8 p; r+ P }
, h" q3 v. `# F1 f0 Q$ U% c3 {6 w- S8 o) c1 X* J2 {' g6 e
  程序最后要调用 ::CoUninitialize();//释放程序占用的COM 资源。
$ n& H! q9 s" P0 d4 P
9 D9 |1 @  s  l# f( t) T( W# o  另外:
& D1 M! U/ n( m/ L# q
  X, k& a4 O; n1 J8 e6 gm_pRecordset->Close(); 注意!!!不要多次关闭!!!!!!!!!!!!
. ^6 [+ z  V, m; [8 Hm_pConnection->Close();
  e- }6 ^# ]# r' E( y" U0 Wm_pRecordset = NULL;
0 W4 Z9 [8 S6 c* Dm_pConnection = NULL;
( c) A! n. Q, v5 R  2. 引入ADO库文件 - X$ c& C) d, D& t# \4 g+ a

" Z, P% f  ^( ~& F5 C4 g  使用ADO前必须在工程的stdafx.h文件最后用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下:
' ^: G  @" Z' a" g  C! z5 y#import "C:\Program Files\common files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF"). }9 Y3 ^+ H5 ?6 U* b1 [* W4 g" M5 K
  ADO类的定义是作为一种资源存储在ADO DLL(msado15.dll)中,在其内部称为类型库。类型库描述了自治接口,以及C++使用的COM vtable接口。当使用#import指令时,在运行时Visual C++需要从ADO DLL中读取这个类型库,并以此创建一组C++头文件。这些头文件具有.tli 和.tlh扩展名,读者可以在项目的目录下找到这两个文件。在C++程序代码中调用的ADO类要在这些文件中定义。
  w# g- k7 N# W: G6 Q9 B3 q! b5 Q   程序的第三行指示ADO对象不使用名称空间。在有些应用程序中,由于应用程序中的对象与ADO中的对象之间可能会出现命名冲突,所以有必要使用名称空间。如果要使用名称空间,则可把第三行程序修改为: rename_namespace("AdoNS")。第四行代码将ADO中的EOF(文件结束)更名为adoEOF,以避免与定义了自己的EOF的其他库冲突。 5 t, R- X% u+ D; V, P, C

  r3 P( v) z# t  3.利用智能指针进行数据库操作 " _% ~3 \$ j, l$ y4 e* p1 c# }
  w7 E& l" Q. A; K3 M. T. A
  在CaboutDlg头文件中定义两个ADO智能指针类实例,并在对话框中加入一个ListCtrl。% q/ N4 s) u9 Z& c

% w7 Y  J2 k! S0 n3 R/ s2 @class CAdotestDlg : public CDialog
( \' U  e' f0 b& U; a; m" e6 n4 v{
# c' m! k3 u6 E& S* C    _ConnectionPtr m_pConnection;3 k0 `( ?; R% ^0 h5 d! M
    _RecordsetPtr m_pRecordset;8 s0 D! g  d3 v# Z
   ClistCtrl m_List; 5 x! k6 N  a- U3 u, a
    ......4 H" E+ e8 T  \5 l: n. A$ }
}     
2 I* w" Z% Z8 G/ r
. m7 B# C0 ]' d1 |- b  ADO库包含三个智能指针:_ConnectionPtr、_CommandPtr和_RecordsetPtr。. i- S/ [# i2 x6 t& {! `* d: H
6 m/ y9 R. F' g. y) I
  _ConnectionPtr通常被用来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。
+ w, I7 Q' J4 C, Y9 }. M- r  _CommandPtr返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时,可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。  _RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定、游标控制等。 % g' U! ?/ e/ i: X& k: v; M
3 \* d' E: B" b" z7 u1 z6 K
  在使用ADO程序的事件响应中OnButton1加入以下代码: 8 k- L7 A7 T& {4 v6 u

; R+ a: v) n" |7 J& C/ B+ c- W4 @7 N4 ivoid CAdotestDlg::OnButton1() 1 S& A* t: V8 b. T4 m9 K+ m5 J
{. C1 k% P  I% h3 y' k, f2 u
m_List.ResetContent();' x+ z: F& E5 u( b& m8 }' M; ]
m_pConnection.CreateInstance(_uuidof(Connection)); //初始化Connection指针
( Q5 ^: t6 ]! |" E9 c0 n8 L9 d* tm_pRecordset.CreateInstance(_uuidof(Recordset));//初始化Recordset指针4 z3 e4 u& |! n! P9 E
try5 O, I- k, ^; T
{# |( s0 t+ g- u% ^% f' H
m_pConnection->Open("DSN=ADOTest","","",0); //连接叫作ADOTest的ODBC数据源9 c" `' ?1 a1 C* V5 K% p
//注意:这是连接不需要用户ID或密码的open 函数
$ [0 ]/ A( S4 M2 F- l/ l$ M // 否则形式为 ->Open("DSN=test;uid=sa;pwd=123;","","",0);
! b! M! g6 S4 V7 R9 t: g7 b
3 a/ S" ~3 A$ K$ s7 ?6 N: Q // 执行SQL语句得到一个记录集把其指针赋值给m_pRecordset
: Y* X' E: i. j* {6 b2 |, | CString strSql="select * from middle";
9 L  Q, n5 X' j! } BSTR bstrSQL = strSql.AllocSysString();
$ N3 T! `/ i2 p# R% I, H1 P' J' R m_pRecordset->Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText);
# h6 A3 I' z" H8 x //adOpenDynamic:动态 adLockOptimistic乐观封锁法 adCmdText:文本查询语句$ t2 v, V* \7 N5 o+ M
while(!m_pRecordset->adoEOF)//遍历所有记录1 j+ C7 P; l+ S. H, D4 r: ^: ^
{
( `- f, K# v2 K7 E' D9 F: v7 r6 G  //取纪录字段值方式之一
. C0 A- H' T, e% w: C, U  _variant_t Thevalue; //VARIANT数据类型" o+ o  F7 _2 r0 r/ ~3 A5 i9 q
  Thevalue = m_pRecordset->GetCollect("BIG_NAME");//得到字段BIG_NAME的值9 J# [5 }( p, Y! J# n- w* {3 u
  if(Thevalue.vt!=VT_NULL)4 s  O! o7 W5 f7 H
   m_List.AddString((char*)_bstr_t(Thevalue));1 [& e( ^5 H0 P+ q. q7 K
  //将该值加入到列表控件中
+ D7 x& m$ i% z' Y9 E; U. H" I( r  F0 ?  C: F' n  W
  //取纪录字段值方式之二
. I" @! ?9 d9 h/ o  |  // _bstr_t Thevalue1=m_pRecordset->Fields->GetItem("BIG_NAME")->value;: K; c2 j! d7 d9 B# K
  // CString temp=Thevalue1.copy();4 L$ e% Y/ t5 \8 \* {
  // m_List.AddString(temp);
  T! v; V6 t0 E: w9 j9 ?  //数据类型转换8 x" D5 g* ~& j
  _variant_t vUsername,vBirthday,vID,vOld;5 i3 A% x9 L3 R: q
  TRACE("id:%d,姓名:%s,年龄:%d,生日:%s\r\n",
- }; |. V4 l2 \4 W& C9 ~; t  vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday);
# z  P1 B! A! u$ ~+ d/ |% j
  a2 `0 D& H8 z  ?/ I$ L  m_pRecordset->MoveNext();//转到下一条纪录' x3 C& m5 e! K
}) Y% |1 U; z0 u/ E. V$ p
m_pRecordset->Close();5 T, n) r1 h8 p
m_pConnection->Close();
. b7 z+ Q* E8 y0 @0 B1 a}9 L9 p* v9 O3 a' I
catch (_com_error e)//异常处理, \# }& V2 g0 z8 Y- D$ d
{
4 z4 w6 [  g) g$ `; U4 G! x AfxMessageBox(e.ErrorMessage());
% c$ f  I9 X- {9 n' k1 m0 t}) I% Q- ?1 c* w+ Z" r7 m0 m
m_pRecordset->Close(); //注意!!!不要多次关闭!!!!否则会出错
& g' o/ j  b0 ]1 x4 I) wm_pConnection->Close();
7 u9 w# M& M, d7 n! N/ tm_pRecordset = NULL;
) p8 ~4 ]$ s$ _m_pConnection = NULL; 1 J# q. Y, n8 d0 v2 b- I' }
} ( c2 T7 U9 a5 k  T

) U; D2 u- F2 j2 m/ y7 H8 P' s  程序中通过_variant_t和_bstr_t转换COM对象和C++类型的数据, _variant_t类封装了OLE自治VARIANT数据类型。在C++中使用_variant_t类要比直接使用VARIANT数据类型容易得多。
" d, c0 e9 v" T& v
  `) Z: `' a' K! |8 z  好,编译后该程序就能运行了,但记住运行前要创建一个叫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-4-17 11:40 , Processed in 0.429182 second(s), 58 queries .

回顶部