QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:50 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
1. 生成应用程序框架并初始化OLE/COM库环境 * u) b& P: I1 R6 ]
7 O2 v1 {& c7 A& @' Q: y
  创建一个标准的MFC AppWizard(exe)应用程序,然后在使用ADO数据库的InitInstance函数中初始化OLE/COM库(因为ADO库是一个COM DLL库)。
9 D( p* R9 j  @( X9 l0 ?$ i本例为: . [0 Y4 I" G. @* F
, |0 W/ J; T1 K6 p
 BOOL CAdotestDlg::OnInitDialog()
  \9 s- h5 t" c$ @; w- k4 @ {, \5 \1 O! p, ]
       ::CoInitialize(NULL); //初始化OLE/COM库环境 % H0 A8 ]4 `. [' U2 s9 z* S
} . ^/ P7 e/ @) N& ]% X" `$ t

. |) d/ O3 ^4 E' Y7 m  程序最后要调用 ::CoUninitialize();//释放程序占用的COM 资源。
7 ^9 W0 |# q, ^" |& f( _, A" s7 d. k  B; ]6 {4 ^; }4 D5 A
  另外:6 n1 O( W8 l3 I
# _3 _8 |! F) ^& Q
m_pRecordset->Close(); 注意!!!不要多次关闭!!!!!!!!!!!!
  I" ]" U3 S) f5 b$ |m_pConnection->Close();
0 s& w/ C; q. D+ K9 qm_pRecordset = NULL;
, ^* z6 j9 {% r: S6 ym_pConnection = NULL; % u% e, e0 p! G+ N) f
  2. 引入ADO库文件
+ |/ u8 z$ r1 Z4 J9 I: t/ M
; X# {( ]3 I) }. L8 l  使用ADO前必须在工程的stdafx.h文件最后用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下:
/ T3 P3 I' ^6 w5 Y; ]2 i; ?#import "C:\Program Files\common files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF"), F; ~1 G- o+ Q* K9 M- V# i+ k6 c
  ADO类的定义是作为一种资源存储在ADO DLL(msado15.dll)中,在其内部称为类型库。类型库描述了自治接口,以及C++使用的COM vtable接口。当使用#import指令时,在运行时Visual C++需要从ADO DLL中读取这个类型库,并以此创建一组C++头文件。这些头文件具有.tli 和.tlh扩展名,读者可以在项目的目录下找到这两个文件。在C++程序代码中调用的ADO类要在这些文件中定义。 5 R- A2 m1 b5 l8 k$ v! _. @
  程序的第三行指示ADO对象不使用名称空间。在有些应用程序中,由于应用程序中的对象与ADO中的对象之间可能会出现命名冲突,所以有必要使用名称空间。如果要使用名称空间,则可把第三行程序修改为: rename_namespace("AdoNS")。第四行代码将ADO中的EOF(文件结束)更名为adoEOF,以避免与定义了自己的EOF的其他库冲突。
4 n) y1 T- M& d' u0 H, }/ `% C
# ^4 q( }$ o& f  3.利用智能指针进行数据库操作 * }' P2 H9 S# O* a: E" ^1 q$ O5 [

& W0 B: X+ X/ T1 H0 L; r# a  在CaboutDlg头文件中定义两个ADO智能指针类实例,并在对话框中加入一个ListCtrl。1 Q2 C* [5 H* {5 L

0 M- s7 d. E+ M5 y; K; g) b2 [class CAdotestDlg : public CDialog6 r9 b: J' w3 G3 n
{! [. ]! L: X6 Z7 B" P" n- w+ c, C  Q
    _ConnectionPtr m_pConnection;# V/ o9 r, t( x" P: o- |& d% c3 r
    _RecordsetPtr m_pRecordset;
/ d0 Z. X& d9 ]" k& R   ClistCtrl m_List; * q: d& X  \! j4 B
    ......) c6 e2 c/ x5 b4 j2 e6 e- A
}     " Z3 i# S6 q- K3 Y- v+ a

7 O# S9 s$ Z' N) V9 d+ T' \9 ]& R  ADO库包含三个智能指针:_ConnectionPtr、_CommandPtr和_RecordsetPtr。  ^/ }! d% N4 i6 ~, g

( \; J" `- V( w! g" g* p  _ConnectionPtr通常被用来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。
. k9 t/ {, ^" h# ], A' B& W9 v+ n  _CommandPtr返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时,可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。  _RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定、游标控制等。 / \0 \3 P) U( T% f. p5 D, Y9 n

- c4 ]+ k  X' \% \9 f3 p  在使用ADO程序的事件响应中OnButton1加入以下代码:
7 E& ]/ K- F* d% A: B
+ k5 N( J, N, b3 c2 Avoid CAdotestDlg::OnButton1() 6 C* }/ j+ I! ~9 Q3 E- u6 ]
{. R8 z0 g' X) z+ {
m_List.ResetContent();
2 S& R: }  y$ x) _; d9 p6 um_pConnection.CreateInstance(_uuidof(Connection)); //初始化Connection指针
% C* p6 s, A. a! k0 wm_pRecordset.CreateInstance(_uuidof(Recordset));//初始化Recordset指针+ s% m$ G. A: n, t6 x7 B
try
& r+ i4 l3 ^' @* v/ t2 E* L{
: y0 `6 m# ^+ }1 P3 _ m_pConnection->Open("DSN=ADOTest","","",0); //连接叫作ADOTest的ODBC数据源+ g6 q3 N$ V% i& M" L
//注意:这是连接不需要用户ID或密码的open 函数
* O( [, F- f/ f  S% j // 否则形式为 ->Open("DSN=test;uid=sa;pwd=123;","","",0);
! T  K& z9 o6 V8 N7 R% l; s7 u8 d- _- R+ U$ H- q% p
// 执行SQL语句得到一个记录集把其指针赋值给m_pRecordset
9 C, z# p* g) H0 L. p" R0 t CString strSql="select * from middle";
/ ?. H+ }& b. R$ t' v BSTR bstrSQL = strSql.AllocSysString();
& R) b- c3 b4 {! K4 q0 _ m_pRecordset->Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText);
- \: V% l6 h& _! |, }3 A( R //adOpenDynamic:动态 adLockOptimistic乐观封锁法 adCmdText:文本查询语句
5 n0 j# ?" u4 ~" ] while(!m_pRecordset->adoEOF)//遍历所有记录
2 m- q6 ?' O4 E- N( d {
- H, b3 c* Y  p' M/ d' S  //取纪录字段值方式之一
* O5 n1 J" `% m" d4 @* d  _variant_t Thevalue; //VARIANT数据类型+ B! x% b+ h: W" b" V
  Thevalue = m_pRecordset->GetCollect("BIG_NAME");//得到字段BIG_NAME的值! E8 \. G& l$ S& t  f; v0 a- L! m  t
  if(Thevalue.vt!=VT_NULL)
& c# [1 F$ S" k" N/ i4 `! a" E' y4 [   m_List.AddString((char*)_bstr_t(Thevalue));
( v: Q' Y+ U& N- w4 p  //将该值加入到列表控件中! Q3 F, T. A" T, ~
2 z5 _2 ]! }; j+ S" w  j, @
  //取纪录字段值方式之二
; W" j; H+ e; c  U  // _bstr_t Thevalue1=m_pRecordset->Fields->GetItem("BIG_NAME")->value;! l9 K9 J7 x8 C; c, [
  // CString temp=Thevalue1.copy();
. _# I6 [; }9 M5 V5 e  // m_List.AddString(temp);
  S1 v5 r( }4 `9 O$ C4 {- {3 D  //数据类型转换
) _' c4 n9 p& I7 {  _variant_t vUsername,vBirthday,vID,vOld;, s# `5 i. B; i
  TRACE("id:%d,姓名:%s,年龄:%d,生日:%s\r\n",* W. D- Q5 x! `1 \7 u
  vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday);. d9 w% w2 h0 z
) Z, H8 J  p* W" J* C
  m_pRecordset->MoveNext();//转到下一条纪录% d4 k8 q+ {6 Y, W/ W6 P' K( D
}
  A& t: j/ ]! p m_pRecordset->Close();0 M4 N- V/ q. ]/ H8 K
m_pConnection->Close();
0 ^9 G2 x% @% h}
8 i  a: N  B6 D# L! b) Jcatch (_com_error e)//异常处理
, D& B1 ^+ n- Z) w+ \) q{$ c! h4 d) Y  p( Q. Q, e/ J
AfxMessageBox(e.ErrorMessage());
" Z& |/ O3 @+ t}
+ ]/ _1 S/ t* {7 bm_pRecordset->Close(); //注意!!!不要多次关闭!!!!否则会出错5 r. p* t! R: t1 i
m_pConnection->Close();3 q8 H& |# A$ D9 I
m_pRecordset = NULL;
' c% ^8 j5 o0 p3 ]$ c3 wm_pConnection = NULL;
- z* Q7 _5 C5 @5 |- o  m) `}
- j6 A" n% t, J$ t7 k' Q$ n
9 ^; d5 a& Q0 `3 [! `  程序中通过_variant_t和_bstr_t转换COM对象和C++类型的数据, _variant_t类封装了OLE自治VARIANT数据类型。在C++中使用_variant_t类要比直接使用VARIANT数据类型容易得多。
) A7 ?4 ?. b( t: j6 `
0 L* A: e" I; K! w4 S  好,编译后该程序就能运行了,但记住运行前要创建一个叫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-18 10:38 , Processed in 0.450107 second(s), 58 queries .

回顶部