QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:50 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
1. 生成应用程序框架并初始化OLE/COM库环境
$ G. E3 o# Q* n" K
2 H' z# E" R0 E9 j  创建一个标准的MFC AppWizard(exe)应用程序,然后在使用ADO数据库的InitInstance函数中初始化OLE/COM库(因为ADO库是一个COM DLL库)。: e+ n9 K0 P$ ~0 |0 v) Z5 Z
本例为:
4 O5 V1 |9 H* w8 K  d2 |) e: r7 o. s8 f7 k$ Y( d
 BOOL CAdotestDlg::OnInitDialog()
+ X2 [& [' [8 S% p {
# ^. U- s0 S2 I       ::CoInitialize(NULL); //初始化OLE/COM库环境
9 W) u! I2 o& c+ c" ^ } 9 j: }) M, y! i. C' c( F% x
0 i9 ]0 w, |: w- x/ ^: u9 z; w& L
  程序最后要调用 ::CoUninitialize();//释放程序占用的COM 资源。4 @. c- `  n1 |

& K2 |4 q. a8 J  另外:
' y3 Q0 x, H1 b. c
. @# K# M$ ?' f1 R% vm_pRecordset->Close(); 注意!!!不要多次关闭!!!!!!!!!!!!
6 W, Y, r) A7 V- Sm_pConnection->Close();
# {, ~0 w! s' s; y" E: b% d9 y( Bm_pRecordset = NULL;2 V5 v6 x# I2 B5 `$ d; Y9 f
m_pConnection = NULL;
, ?9 W( ~! u  ]: l# o  2. 引入ADO库文件
/ O* @! y" ~% {  G9 t3 `( b. m: _( y, z5 m/ Y5 }. ~# z0 I4 p
  使用ADO前必须在工程的stdafx.h文件最后用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下:9 Z' O/ w& \8 _  Q5 d$ P
#import "C:\Program Files\common files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF")
9 Q* a1 E- T8 _  ADO类的定义是作为一种资源存储在ADO DLL(msado15.dll)中,在其内部称为类型库。类型库描述了自治接口,以及C++使用的COM vtable接口。当使用#import指令时,在运行时Visual C++需要从ADO DLL中读取这个类型库,并以此创建一组C++头文件。这些头文件具有.tli 和.tlh扩展名,读者可以在项目的目录下找到这两个文件。在C++程序代码中调用的ADO类要在这些文件中定义。
2 N7 p5 j- x1 r  K   程序的第三行指示ADO对象不使用名称空间。在有些应用程序中,由于应用程序中的对象与ADO中的对象之间可能会出现命名冲突,所以有必要使用名称空间。如果要使用名称空间,则可把第三行程序修改为: rename_namespace("AdoNS")。第四行代码将ADO中的EOF(文件结束)更名为adoEOF,以避免与定义了自己的EOF的其他库冲突。 2 n" @# ~- O. i
- H3 Z! c8 l( [6 L
  3.利用智能指针进行数据库操作
) S2 h- e) S+ \% s, z' a6 P: V+ a5 k- t3 p9 L, D
  在CaboutDlg头文件中定义两个ADO智能指针类实例,并在对话框中加入一个ListCtrl。- M9 [! w5 K: s& G# r/ k7 f9 l* h8 j
- s4 ^8 S7 x- I
class CAdotestDlg : public CDialog3 q0 y% M# D* h
{. z* h5 x% }& x
    _ConnectionPtr m_pConnection;5 e" D  @; N3 q
    _RecordsetPtr m_pRecordset;
5 ?2 \/ p2 w; C2 Q# r" O- f   ClistCtrl m_List;
# O2 v5 \+ ~2 D7 o$ H" D  a    ......
! H$ p5 p; ]* @, x}     
! d2 N0 U& g/ b6 `* o7 {
- |9 h# P+ c; ~7 F+ W9 w' X. S  ADO库包含三个智能指针:_ConnectionPtr、_CommandPtr和_RecordsetPtr。8 ]3 ~3 A( j7 _# ~

' g. s2 {: T# u% A$ g& `/ Q$ q  _ConnectionPtr通常被用来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。( x" d; {; H" L" {8 L' u- |# `5 P  U
  _CommandPtr返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时,可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。  _RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定、游标控制等。 5 S3 }! f5 b+ f- e5 w" H

8 Q5 v2 q% Q: b% @: }, [  在使用ADO程序的事件响应中OnButton1加入以下代码:
+ [' z- g+ u; M; w0 p0 ?
& G/ a2 z1 L: a! s! q( A8 n; E6 Bvoid CAdotestDlg::OnButton1() 2 \2 K. s( b/ ~3 C! Z6 ?
{
) J6 r1 f/ Z  |  G3 um_List.ResetContent();. L: n6 P$ N* Z& J7 i2 ?
m_pConnection.CreateInstance(_uuidof(Connection)); //初始化Connection指针
1 }3 w! L* Y$ s' Xm_pRecordset.CreateInstance(_uuidof(Recordset));//初始化Recordset指针6 M* y# g3 c. F/ W/ H. a  ]
try5 K6 j- }, L! D3 U. t
{
( H, v: W& w( ?. m4 h6 f, H m_pConnection->Open("DSN=ADOTest","","",0); //连接叫作ADOTest的ODBC数据源1 m6 |& B* B7 ^. a. {7 A
//注意:这是连接不需要用户ID或密码的open 函数! b. ~, \, _* @4 [% P' ?9 h) q
// 否则形式为 ->Open("DSN=test;uid=sa;pwd=123;","","",0); # V/ [' l3 k% s: k1 I0 r8 ]5 P$ h
( t& `$ T, J. b. q& F$ u
// 执行SQL语句得到一个记录集把其指针赋值给m_pRecordset
" a, g1 b& E% r1 z" j CString strSql="select * from middle";. F. N) d6 b) @! J0 D( J2 `
BSTR bstrSQL = strSql.AllocSysString(); * o! O7 `( S* v. U
m_pRecordset->Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText);
( g2 h  b5 d! Z+ r. j7 p. {! d //adOpenDynamic:动态 adLockOptimistic乐观封锁法 adCmdText:文本查询语句1 v$ k% v- n* g2 W5 `, ]
while(!m_pRecordset->adoEOF)//遍历所有记录
7 j, F5 H! _* _- H7 _  ^/ s# ^ {
4 I" Q$ W# f" H/ k/ e) B$ n  //取纪录字段值方式之一9 T9 v5 N- P; `6 V2 f
  _variant_t Thevalue; //VARIANT数据类型
2 F# z, j; K* c2 v) A  Thevalue = m_pRecordset->GetCollect("BIG_NAME");//得到字段BIG_NAME的值
: r" A- [& _6 n5 D  if(Thevalue.vt!=VT_NULL)
2 }# s% s4 U7 ]& x1 E# H   m_List.AddString((char*)_bstr_t(Thevalue));
9 q6 ^  l) C, t+ G. Y  //将该值加入到列表控件中: u1 ~7 c) D( Y+ G

6 [" b( F% j! ]- l/ ?' b' V' R  //取纪录字段值方式之二! I0 M2 r5 B" A/ a" K
  // _bstr_t Thevalue1=m_pRecordset->Fields->GetItem("BIG_NAME")->value;0 i  c# v$ `2 ]
  // CString temp=Thevalue1.copy();
, ?- \; ?6 f9 p$ [5 b  // m_List.AddString(temp);
+ r9 k/ x9 v. X5 r  //数据类型转换
; x+ z0 F2 o; F7 S  _variant_t vUsername,vBirthday,vID,vOld;
, k6 h" ?8 ?+ L/ V  TRACE("id:%d,姓名:%s,年龄:%d,生日:%s\r\n",% j! J% `) f' q, `5 D5 m3 b
  vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday);
+ J8 N1 V. C6 v& C( V& L4 ^- w& b2 A' J" j$ t6 d  d
  m_pRecordset->MoveNext();//转到下一条纪录
3 y5 R% x+ T* G) `# V6 c }  F/ P5 }9 R8 i4 D: N5 |
m_pRecordset->Close();
( {! s1 e" A9 a; H% J: q) Q6 T m_pConnection->Close();, K9 ^6 O+ f3 [
}
9 y6 c' D4 h, _catch (_com_error e)//异常处理. m* A& }+ o8 h  }* w, }
{+ N$ E8 T+ x& F$ E
AfxMessageBox(e.ErrorMessage());- e7 J: j8 R+ Z
}
& L& W% x* o7 F" Z, l2 x/ \# Qm_pRecordset->Close(); //注意!!!不要多次关闭!!!!否则会出错$ \4 E0 |" ]6 @; A$ S
m_pConnection->Close();( v5 e  Q8 J& G4 s! v; u
m_pRecordset = NULL;2 J8 U( U' x9 T9 _0 V
m_pConnection = NULL;
( z/ j6 Y1 G! n+ o: j2 h- C, H} ! J6 f0 Q+ |$ ?' {
# w8 o% v# W! z( O: Q4 Y# i
  程序中通过_variant_t和_bstr_t转换COM对象和C++类型的数据, _variant_t类封装了OLE自治VARIANT数据类型。在C++中使用_variant_t类要比直接使用VARIANT数据类型容易得多。 . x4 }. _! E; ?( o

4 l0 l2 R8 z. D( A8 k3 I  好,编译后该程序就能运行了,但记住运行前要创建一个叫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-7-19 20:20 , Processed in 0.391739 second(s), 58 queries .

回顶部