QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:50 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
1. 生成应用程序框架并初始化OLE/COM库环境 % m( H6 _+ r5 E  Y1 ^

1 O- M' q, h1 u0 h  创建一个标准的MFC AppWizard(exe)应用程序,然后在使用ADO数据库的InitInstance函数中初始化OLE/COM库(因为ADO库是一个COM DLL库)。2 N* b* \' Z5 x8 Y, N4 V
本例为:   k8 j" X$ Y2 O$ T

2 ^6 j2 G# C9 x7 l4 Q BOOL CAdotestDlg::OnInitDialog()  |" c' R- f' W$ t* T1 o6 c$ P
 {
, T& P2 y5 R# L! u) f; i       ::CoInitialize(NULL); //初始化OLE/COM库环境
! V6 E, \, x2 q0 B  y) B# R% ^7 W } ( ~" Q- v3 l5 ^# }" e+ ~! j7 q

: C& h( R/ ]9 G0 g2 K. }4 Q  程序最后要调用 ::CoUninitialize();//释放程序占用的COM 资源。+ X, N7 M3 k$ x3 q3 j2 m% h

' q  n+ ?$ k+ h) D  另外:
- Y* L( a1 b* g6 k% v
) F% H  V. d' p8 P! _% s4 K  v" Vm_pRecordset->Close(); 注意!!!不要多次关闭!!!!!!!!!!!!5 U' p* Q& Z/ |& T/ v0 q+ e
m_pConnection->Close();7 H2 ]* d7 K& G$ z
m_pRecordset = NULL;
  H( r0 y$ q" |: `$ H  {3 Q, w2 nm_pConnection = NULL;
3 B( ^3 J  F$ K' P4 }  2. 引入ADO库文件 ( y# L( u0 k1 L# {5 b/ |0 ?

# l! I$ Z5 `1 C0 K6 i! j" u9 o; K  使用ADO前必须在工程的stdafx.h文件最后用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下:
" J- x# c. p1 h5 y% b3 T' Q$ k" g#import "C:\Program Files\common files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF")- D- [% L; j: |5 H. e
  ADO类的定义是作为一种资源存储在ADO DLL(msado15.dll)中,在其内部称为类型库。类型库描述了自治接口,以及C++使用的COM vtable接口。当使用#import指令时,在运行时Visual C++需要从ADO DLL中读取这个类型库,并以此创建一组C++头文件。这些头文件具有.tli 和.tlh扩展名,读者可以在项目的目录下找到这两个文件。在C++程序代码中调用的ADO类要在这些文件中定义。 ( ^; @; D4 x* O- ^, v) v
  程序的第三行指示ADO对象不使用名称空间。在有些应用程序中,由于应用程序中的对象与ADO中的对象之间可能会出现命名冲突,所以有必要使用名称空间。如果要使用名称空间,则可把第三行程序修改为: rename_namespace("AdoNS")。第四行代码将ADO中的EOF(文件结束)更名为adoEOF,以避免与定义了自己的EOF的其他库冲突。
/ ^! i# e9 K' U" M3 R3 F) O" I: Q2 I  e/ j8 V* w
  3.利用智能指针进行数据库操作 * t0 @, j' b8 N6 L# ]: T

* L, J2 I/ z2 u  在CaboutDlg头文件中定义两个ADO智能指针类实例,并在对话框中加入一个ListCtrl。2 d  w6 X' b/ v' \

; x, q0 ^" _7 uclass CAdotestDlg : public CDialog
  @, l2 `" H; n2 `* P  A{
/ {- `- b7 ^* N7 r9 r, I0 L5 ?    _ConnectionPtr m_pConnection;" |3 E' `& U; Y: I9 W- X, E
    _RecordsetPtr m_pRecordset;& V5 k# \7 |" C3 ?: t( V
   ClistCtrl m_List;
; c4 f; p# K1 `$ `' N5 ^/ o    ......
. l5 P$ a2 _* H9 o}     
; E) z% ?! f! \' M' M6 \1 e3 K5 A) c2 w
  ADO库包含三个智能指针:_ConnectionPtr、_CommandPtr和_RecordsetPtr。$ q- {  f) E, ^) x

, w* z! R2 Z$ E  _ConnectionPtr通常被用来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。
# |; q' D7 j7 A& j4 w& f  _CommandPtr返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时,可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。  _RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定、游标控制等。
$ B, ]' E/ V* a6 g
& L5 z7 i4 k5 Q! a; k! I  在使用ADO程序的事件响应中OnButton1加入以下代码:
, P" X! F0 n9 |
0 S5 W' {8 q' Avoid CAdotestDlg::OnButton1() - Q  p; D* [, x7 F7 ?
{' V( D& k. X- Z! c3 Y6 e
m_List.ResetContent();; _  D. h3 S* y& C" f+ Q+ C
m_pConnection.CreateInstance(_uuidof(Connection)); //初始化Connection指针
4 {4 n! E3 Q" R& ]7 L; A: d. ]m_pRecordset.CreateInstance(_uuidof(Recordset));//初始化Recordset指针
4 v  X6 F( L+ i" J# J( Htry
7 H0 Q6 J% j" M5 }& U: |' N{2 R; P& s7 k9 s7 S9 O4 }
m_pConnection->Open("DSN=ADOTest","","",0); //连接叫作ADOTest的ODBC数据源+ x  @8 a5 C7 u/ r
//注意:这是连接不需要用户ID或密码的open 函数
' V$ _9 |) D$ U2 o // 否则形式为 ->Open("DSN=test;uid=sa;pwd=123;","","",0); . t# m- h* @+ f+ I
+ Z! ~6 _% [* q5 o& d2 S/ M  y( l
// 执行SQL语句得到一个记录集把其指针赋值给m_pRecordset
& q6 h. K8 ~- n- |; j+ p- Q CString strSql="select * from middle";4 z) p0 z( U% `" l& u% f/ w, Q* x
BSTR bstrSQL = strSql.AllocSysString();
' \8 U$ I  L# S2 N9 e m_pRecordset->Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText); 6 S) c2 N. Y1 e2 |8 S6 {' `
//adOpenDynamic:动态 adLockOptimistic乐观封锁法 adCmdText:文本查询语句0 b7 V5 R, R" W( O5 F, c. n# [# N
while(!m_pRecordset->adoEOF)//遍历所有记录' R  K# A% b5 g
{ + |/ d  L0 v0 G6 h
  //取纪录字段值方式之一8 M; M7 j* S7 R0 A5 n
  _variant_t Thevalue; //VARIANT数据类型4 y6 O# h. B' [5 d- l) q
  Thevalue = m_pRecordset->GetCollect("BIG_NAME");//得到字段BIG_NAME的值7 u$ i5 c6 n+ H& Y  X2 c
  if(Thevalue.vt!=VT_NULL). A* i2 i# q, K- M2 n9 @: N
   m_List.AddString((char*)_bstr_t(Thevalue));
9 K- b6 _$ c1 _/ H( G  //将该值加入到列表控件中
* N8 A$ {: u" k- L0 O
/ Q2 n+ F$ }, n7 Y4 s  V! Q- M( f' o  //取纪录字段值方式之二
0 T; U8 a& |. L6 ~+ ?  // _bstr_t Thevalue1=m_pRecordset->Fields->GetItem("BIG_NAME")->value;+ @: V' M' X* a6 y! }2 b/ }
  // CString temp=Thevalue1.copy();$ h: Q) R$ g0 h+ P% ]
  // m_List.AddString(temp);8 k$ e" [6 O9 B
  //数据类型转换
& I2 A$ w* p! @4 p  {$ n  _variant_t vUsername,vBirthday,vID,vOld;5 B( N( E+ b* i: |$ {# e9 d. J
  TRACE("id:%d,姓名:%s,年龄:%d,生日:%s\r\n",
' ?( F/ F( ]! ?* U2 K$ T# T) Z  vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday);
$ U8 T8 o* g4 M( B$ G  @" b* |. Y2 p) H8 ?5 U& x" i# g1 T
  m_pRecordset->MoveNext();//转到下一条纪录
) u% o$ d# j  x# W; f: V7 k- m }
( M& h% ^6 ?/ a6 I: A. s* p m_pRecordset->Close();
0 K! P% Q# u& @* A" H8 M m_pConnection->Close();# N% ~, c" l2 c1 m2 Y2 I6 S9 e
}
' q; k9 P5 Q0 X' a% Jcatch (_com_error e)//异常处理( u* [; X8 [% d* G. Y% l; K
{# t' _1 t0 l. q  u& O: i
AfxMessageBox(e.ErrorMessage());
! r' A: w2 l& {0 b. }5 L9 C}
- c. L  [8 T# j" v1 tm_pRecordset->Close(); //注意!!!不要多次关闭!!!!否则会出错
. y) k* Z# o$ w+ H6 {m_pConnection->Close();1 H% z7 p6 {, Q. A+ G! d* \
m_pRecordset = NULL;. [/ v, ~6 [& J: M& i( u
m_pConnection = NULL;
8 \  a; j8 C2 D5 y} ) K5 _0 A6 k' H) \

1 D* Z- a5 k8 n& W0 z2 l: ^. Z8 g  程序中通过_variant_t和_bstr_t转换COM对象和C++类型的数据, _variant_t类封装了OLE自治VARIANT数据类型。在C++中使用_variant_t类要比直接使用VARIANT数据类型容易得多。
/ J, M7 J- a5 J* x# S# I8 ?; ^7 e. B  ]) t" J
  好,编译后该程序就能运行了,但记住运行前要创建一个叫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:08 , Processed in 1.040361 second(s), 58 queries .

回顶部