QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:50 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
1. 生成应用程序框架并初始化OLE/COM库环境 % h' t+ F( H0 n/ b7 s
$ y* f2 y0 j" q, d9 @4 Z
  创建一个标准的MFC AppWizard(exe)应用程序,然后在使用ADO数据库的InitInstance函数中初始化OLE/COM库(因为ADO库是一个COM DLL库)。
- R* @2 g- ]3 o% L本例为:
  V5 z8 y2 j8 o
0 }5 A- `5 V: R  ^0 S; ^% z BOOL CAdotestDlg::OnInitDialog()
0 B. J7 ]& B3 Y1 R9 c  Z) L1 L {
* Q, C7 {& ~: A, [       ::CoInitialize(NULL); //初始化OLE/COM库环境 3 q7 v0 H7 v" H# T' l+ W
}
2 T- _" ]) U$ g. S' i  ~* H8 z; }% u' ]/ Q
  程序最后要调用 ::CoUninitialize();//释放程序占用的COM 资源。
3 c2 F: {" H7 e# R2 Y/ M& I0 \  H, W' e- r. C( R. P, o; v0 v0 h  C! ?8 C) }
  另外:* \; S' g) }* H$ c

; u1 l9 }" t+ j  a9 Im_pRecordset->Close(); 注意!!!不要多次关闭!!!!!!!!!!!!1 \1 l! x, B  B- r2 e: L2 g4 b8 [5 G
m_pConnection->Close();
0 O- J  ?' h; nm_pRecordset = NULL;
4 F$ q) ]& e, }& Nm_pConnection = NULL;
( h- o# b: w" r  2. 引入ADO库文件 " K& ^, k5 f/ r
3 N  g* v0 s9 O+ l2 f
  使用ADO前必须在工程的stdafx.h文件最后用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下:
+ h* x- A0 x& B  o#import "C:\Program Files\common files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF")
( t7 E/ u4 O( O) w) T* P% M" J! ^  ADO类的定义是作为一种资源存储在ADO DLL(msado15.dll)中,在其内部称为类型库。类型库描述了自治接口,以及C++使用的COM vtable接口。当使用#import指令时,在运行时Visual C++需要从ADO DLL中读取这个类型库,并以此创建一组C++头文件。这些头文件具有.tli 和.tlh扩展名,读者可以在项目的目录下找到这两个文件。在C++程序代码中调用的ADO类要在这些文件中定义。
9 X6 T, O( G$ }0 n   程序的第三行指示ADO对象不使用名称空间。在有些应用程序中,由于应用程序中的对象与ADO中的对象之间可能会出现命名冲突,所以有必要使用名称空间。如果要使用名称空间,则可把第三行程序修改为: rename_namespace("AdoNS")。第四行代码将ADO中的EOF(文件结束)更名为adoEOF,以避免与定义了自己的EOF的其他库冲突。
; `0 b6 b$ v# |) k/ g/ J* P
2 z' S5 h1 F2 `- S- a" r  3.利用智能指针进行数据库操作
$ W" Z' ~# y+ L' \0 C! r+ C+ T" g* @( u, E, z* J
  在CaboutDlg头文件中定义两个ADO智能指针类实例,并在对话框中加入一个ListCtrl。
' Z2 S8 o: U" G
" g4 Q0 v' Y  ^, j+ M% yclass CAdotestDlg : public CDialog
( {" V, M; ^, c, ?* H! S( i; E{
; U& d& U6 `, m/ a% ~$ t/ `    _ConnectionPtr m_pConnection;; z. a8 A2 }  E# q# _* a
    _RecordsetPtr m_pRecordset;
% z5 l% i$ K  h/ X- p& I% E* A   ClistCtrl m_List; # d6 k) {# I4 p& N" `: G$ u+ ]
    ......6 |4 p, h+ t8 g- D5 q' q" {
}     8 W* S0 {% u% \; H5 y
' U) `; @: t" F% `4 }: f* q6 H& U. ^$ l/ }
  ADO库包含三个智能指针:_ConnectionPtr、_CommandPtr和_RecordsetPtr。2 g& b% ^! A( G

( u$ g7 d! O* S: ?: Q& W4 p  _ConnectionPtr通常被用来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。
. j- O/ P) [9 `. o: @" R% M! E  _CommandPtr返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时,可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。  _RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定、游标控制等。
$ y; _. t; p: {! E- W
+ R1 g8 J( P2 x; U: {/ Q. Z  在使用ADO程序的事件响应中OnButton1加入以下代码: ( ]6 ^- O0 i& ]; X; Y9 [
& |) ~* e! Z+ v( `  [* \
void CAdotestDlg::OnButton1() # K7 ^1 r6 ~9 q2 w
{. f5 C* J+ y& k, C, \6 a( h& p
m_List.ResetContent();2 h9 p% c+ s/ M/ K( U
m_pConnection.CreateInstance(_uuidof(Connection)); //初始化Connection指针
1 H1 q6 |2 o2 ~m_pRecordset.CreateInstance(_uuidof(Recordset));//初始化Recordset指针6 V9 Q: U. ^1 V/ Y6 |
try$ x% B. J$ o, e3 V* X) c; M
{) v2 `  v$ Z5 C; e* }5 n2 {
m_pConnection->Open("DSN=ADOTest","","",0); //连接叫作ADOTest的ODBC数据源3 o& B- g9 h2 t
//注意:这是连接不需要用户ID或密码的open 函数
3 V7 J  R3 b1 q/ X; w // 否则形式为 ->Open("DSN=test;uid=sa;pwd=123;","","",0); ) \3 J* ?+ R- y8 B
7 v; x! p) z& k$ A0 M
// 执行SQL语句得到一个记录集把其指针赋值给m_pRecordset
3 {& j4 \% e1 f6 x6 D- j9 W: s8 v CString strSql="select * from middle";
* J& ]7 r2 w$ J BSTR bstrSQL = strSql.AllocSysString();
" t  O" j/ I/ w, p m_pRecordset->Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText); % j3 |+ O: D* h2 `' }) x4 T
//adOpenDynamic:动态 adLockOptimistic乐观封锁法 adCmdText:文本查询语句
7 \% M$ e/ m' b" W+ l9 ^3 _$ x while(!m_pRecordset->adoEOF)//遍历所有记录/ U: t/ C% I& `9 d3 t1 g
{ 0 S# r( j& E+ V4 r
  //取纪录字段值方式之一
5 g; N( U  M8 K2 t5 ]9 Z  _variant_t Thevalue; //VARIANT数据类型! x# M! d  E1 F, g: \1 g
  Thevalue = m_pRecordset->GetCollect("BIG_NAME");//得到字段BIG_NAME的值
$ e, q4 M& L2 Y0 b  if(Thevalue.vt!=VT_NULL)4 H6 a* @/ Q& s# E; A2 F
   m_List.AddString((char*)_bstr_t(Thevalue));8 l5 K+ `* I' d1 v, `
  //将该值加入到列表控件中# K2 i" U7 x0 o" K

9 X! k# D5 e: [" s! S3 Q  //取纪录字段值方式之二
/ ?* n% o- d- R& b  // _bstr_t Thevalue1=m_pRecordset->Fields->GetItem("BIG_NAME")->value;
1 x  [% L3 t6 ?6 x6 F  // CString temp=Thevalue1.copy();
" `2 n- v7 B+ k- k  // m_List.AddString(temp);9 H8 {! ]. f* a" W$ r* q
  //数据类型转换
! r  u- E& u& B- r. K( S  _variant_t vUsername,vBirthday,vID,vOld;
: }: m! k6 Y2 n, E/ ~  TRACE("id:%d,姓名:%s,年龄:%d,生日:%s\r\n",% g/ t+ d$ w& ^9 J4 Y  Y5 L8 v: f+ S
  vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday);
, {6 [. s0 w, b2 U/ }5 J/ j
; p5 b7 M2 Y7 [" d. u* F$ W& r9 o  m_pRecordset->MoveNext();//转到下一条纪录
4 q6 D9 r7 Z' L  `8 { }2 k: m: z7 z6 G! M6 H2 Z
m_pRecordset->Close();% i4 M. U4 P5 y+ Y# k
m_pConnection->Close();
* o- A& o" \3 H# h+ ~+ y6 \: F}+ N, B$ `3 k& F
catch (_com_error e)//异常处理
- E1 {# W! G0 o9 `2 \; @{
/ `( L+ }- I4 W& f% U( v' b AfxMessageBox(e.ErrorMessage());4 ]! |3 ~2 `/ v; Q5 U; s, S" B
}
; b' b+ `9 ^/ D' \9 b9 t$ Em_pRecordset->Close(); //注意!!!不要多次关闭!!!!否则会出错- L# e1 K* o( Q: ~! E6 N
m_pConnection->Close();
. n: S% ?9 t! B7 i, qm_pRecordset = NULL;
$ D/ m, X% O2 `m_pConnection = NULL;
- V' J2 I5 z2 W9 s9 K4 c}
0 R4 L/ z% ?0 r4 f
1 J# r3 O  I$ @1 S# O& i6 F  程序中通过_variant_t和_bstr_t转换COM对象和C++类型的数据, _variant_t类封装了OLE自治VARIANT数据类型。在C++中使用_variant_t类要比直接使用VARIANT数据类型容易得多。
. _; V# b% l4 A( N# f7 d
# V' R/ x, P0 o  好,编译后该程序就能运行了,但记住运行前要创建一个叫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-3 15:42 , Processed in 0.406520 second(s), 57 queries .

回顶部