找回密码
 注册
搜索
查看: 4122|回复: 0

[收藏]VC++中调用ADO的常用方法

[复制链接]
发表于 2004-1-31 18:14:29 | 显示全部楼层 |阅读模式
  对于在WINDOWS上编写数据库程序的程序员来说,ActiveX Data Objects (ADO) 是最常使用的技术了,通过ADO可以简单的实现数据库的连接以及数据访问。但是在VC++中使用ADO时,却因为是使用COM的方式来调用,常常出现一些系统无法编译通过,或使用中程序非法出错的问题,在这里想大概介绍一下VC++中调用ADO的常用方法。9 P/ x; Z* }$ y" Z, u2 J: F
% |7 A& h0 _& r
1、 用import导入ADO 的 COM 文件msado15.dll4 s5 W! C% W5 h0 R
) G7 Z' j9 K, |
例如:& z# e- N) r+ k: K: ?/ E. n
) Q) b+ m8 t+ m! a. M
  #import "C:\Program Files\Common Files\System\ADO\msado15.dll"\
* t4 J7 ]. O- ?% x1 j; N. ~3 X. `4 M/ f# E0 R* }$ \2 [2 ]
   no_namespace
9 i- a( W/ K& k  F$ n3 u: j4 \+ I3 v* c# X+ v
) u0 F+ F% u! S* y
2、COM 使用时初始化
9 \1 C( H7 J, P  N* b6 M% j8 m* k0 ^( v
HRESULT ComInit()# q2 [& t1 V% e( k5 w/ l* |
{ $ ?& C1 q, d' S
    HRESULT hr = S_OK;             // 默认返回值
/ X, I) F2 K% s, h    if FAILED(CoInitialize(NULL))  // COM 初始化调用" l/ R& D' `' E# C7 V. Z
    {; L( M. h4 n& T4 `0 e  b
        CoUninitialize();& x( i( w* z. u" {3 l
        hr = E_UNEXPECTED;. @/ o) y8 ^/ B
    }
& p! r- S: E+ e    return hr;5 U3 O5 |' ~9 s) h5 `  ?$ }) p! ~
}) H9 B* A& T' B9 N

( ?; L3 A' g( P/ X- O0 l, V6 l( n3 m( @  W  \8 ?
3、建立数据库连接
9 v  l2 Z0 d' U$ }6 F2 j/ Q7 Q3 D
' s& Z' n3 m; U# w6 M" AHRESULT ConnectToDB( LPSTR pUserId ,                    // 用户名
& o" |1 m* B- m$ m* Y, c) t                     LPSTR pConnString,                 // 连接字串 # \% W% ^( Q0 C$ b  I# P. C0 \- s
                     LPSTR pUserPassword ,              // 用户密码
6 i! F3 S4 A' O, Z4 F7 @8 U7 P                     ConnectOptionEnum ConnectOption )  // 连接参数
( G4 [$ z+ Z$ ^8 {' _' @4 K! R6 Y3 {{" V7 O- [* ~, w9 ?/ h% O$ c/ v
" {  X. d1 e5 q& p) p2 C7 `! }
    HRESULT hr = S_OK;        // 默认返回值
, n$ ], k: C, [" f% S    _ConnectionPtr ptrConn;   // 定义Connection对象
; Q) v7 j: S/ O! Y0 F3 G+ v/ D
7 R' x0 U9 X+ w8 g9 S0 J    try, g. a2 j- ]9 e; v( V' }5 h+ K4 A
    {0 n' P8 z) p" S
        // 创建一个连接实体
# M6 c/ P4 j7 P/ R! S5 N        hr = ptrConn.CreateInstance( __uuidof(Connection) );
& ~# S' C; p8 K) o7 z: f! x; ^: ?( t& O+ r3 `, ]( ], o+ U% R. G( X
        // 设定连接等待的最大秒数,默认是15秒. u" O4 Z+ @, b+ D* f
        ptrConn->ConnectionTimeout = 20
( J% f8 N( H4 p' G' m2 r' q% s* l! g7 l6 \2 x" T
        // 打开连接; t* C6 D1 [, w$ N
        hr = ptrConn->Open( pConnString, pUserId, pUserPassword, ConnectOption );) V+ @) X: H' S+ j; g' F- I
        return hr;
, w. J; ]6 Y: b2 ~& O" a. [    }
+ R$ I4 w4 w- W    catch( _com_error & pComError )
4 @, V( D* i/ h: t5 d; w    {6 I# }- N1 R2 m; ~8 c9 V
        …… // 错误处理
* {1 G9 i0 I; k        return E_UNEXPECTED;
: ~9 f( ?: v9 ]1 H" t    }+ n- E/ M  q' h0 h$ g, @
}6 ?+ A! L! c, r0 H

! L( L" }/ y" K. _
( l0 K1 g3 ]) C" T1 c: R4.执行一个SQL 查询,得到数据集(recordset)
0 f& f& d- U# G
5 R' w0 Y$ }, _1 V, X8 C, T! r_RecordsetPtr GetRecordSet( LPSTR strSql, _ConnectionPtr ptrConn )
, V8 o0 a; d. `+ f{7 b  f( @! U6 k. I- H/ L7 A
    try
  K2 [4 y0 N3 I9 x: ~! i" Q5 E    {
# C6 R$ o8 j# L% |        RecordsetPtr ptrRS; // recordset 对象, F  K: I* S, Q, W8 v3 ?
$ M# c% D. s. G1 z  b" e! C8 Z
        // 创建recordset 对象实体
: X3 U) ?1 }6 D( V        ptrRS.CreateInstance( __uuidof(Recordset) );
7 K5 `8 F( b/ }        ptrRS->Open( strSql, ptrConn.GetInterfacePtr(), adOpenForwardOnly, + G8 k% |: t0 L
adLockUnspecified, adCmdText );
. X$ k% M/ r. n, t7 n: |& Z8 U+ _8 p5 R* J9 X
        或者( u3 w* ?/ {0 y1 D2 U# m
        ptrRS = ptrConn ->Execute( m_ strSql,NULL, adCmdText );+ Y4 }% A4 L) U. ?, I* y
        return ptrRS;8 i- {: O& A- ]0 i* ^+ Q
    }
3 y2 w: z5 ^: F    catch( _com_error & a_pComError )
3 p) C. ]! |0 B& B: \* z8 i! p    {
& i; T) B5 j( x- J3 e, V5 X        ….// 错误处理
' F5 l' E8 k$ y, ~+ A$ v        return NULL;
4 Q/ P4 g4 l; F8 P0 `    }
2 S0 N9 e* g1 }( d* B: i}& R9 }8 {% L% F5 K$ g

( m  H  S" J) d9 X: e
$ o" G+ m5 ^% k( S! r- ?7 [# X5.通过数据集(recordset)得到列的名称
0 V$ P, F& g7 ^( ^+ O( V& P% ?# J3 v/ `
HRESULT GetColumnNames( _RecordsetPtr ptrRs,        // recordset 对象
; J% N9 H! l+ h; n+ h                        char strColNames[][255],
! Z) s8 g$ o" d$ B( e7 w                        DataTypeEnum iColTypes[] )% a9 Y& r  Y8 }, U& Z* N# x8 r, D
{# @6 E4 D2 j5 Y. \/ v
    try" P5 W5 I: u& d+ l
    { // 参数变量
8 t) u6 u9 r, u, k3 S        _variant_t l_vaIndex;( v7 {6 L  M' ]; F4 n$ ]+ a* `

' A$ p9 k% e2 j        l_vaIndex.vt = VT_I2;
$ ]7 H1 b! h( s( J/ L9 _
4 n2 F& ]! f: I- p        // COLUMNS总数1 m, i8 S+ _% [" |2 o5 ~
        long lColCount;
$ t/ }+ r6 Z6 ~% z, e
$ ^3 s- w& ]) [' o. `1 C        lColCount = ptrRs ->Fields->Count;' z$ q( t" w; O: T

. r0 ~1 y% P3 Q4 d2 @        // 循环取得列的属性和名称
2 q) t( k2 |9 T' h* E8 F3 g- b        for( int iIndex = 0 ; iIndex < lColCount; iIndex++ )
- j& ^0 h% P1 j5 _        {
$ i& E1 B) i) K1 T! n4 ]* k8 Q            l_vaIndex.iVal = iIndex; // 设置循环索引" t& R/ `( D$ U& [: X% |

* D. h3 z# g3 ~$ M0 Y# x& b            // 取得字段名称+ I3 k$ E, ?% y& M6 b2 c% ~0 X
            sprintf(strColNames[iIndex], "%s", (LPSTR)ptrRs ->Fields->GetItem(l_vaIndex)->Name);
4 x9 W+ r0 ^% M0 I' y- v, U6 N8 F
            // 取得字段属性
3 s) a5 {. i( I& d4 ^/ p; n3 E% ?( g            iColTypes = ptrRs ->Fields->GetItem(l_vaIndex)->Type;
5 g/ y% J" O) X; J) `        }
2 d# f, k9 F7 M        return S_OK;  Q# u( ]  t! @& V
    }
6 L0 W% c4 L# H    catch( _com_error & a_pComError )
8 s& O2 [# h. L8 |    {7 j  N9 Z6 X, v' g) h8 O: U5 X
        …. // 错误处理% i9 X5 |) n/ A! ^
        return E_UNEXPECTED;; u+ f4 ?6 N4 c4 {3 Y
    }
: u; `& f( C) D$ O, G+ _    catch(...)& o+ t( r  V7 t) t9 ?7 ?
    {# k6 M# D! y$ T! D6 `& i4 T) D+ I
        …. // 错误处理
/ M+ |6 ]8 H* Z* x: u8 V        return E_UNEXPECTED;! s2 G3 L& c- j0 G3 J8 X
    }" {' E0 k6 u/ v/ z
}
/ F4 E, @( |8 G. _8 H" |. D' m0 w/ k

: j* H5 e- J+ _: j* g9 C/ K6.通过数据集(recordset)得到当前行记录
9 k' t& O: O6 O* l5 \
5 L: a7 ^$ W$ @) ZHRESULT getOneRecord( _RecordsetPtr ptrRs,$ i/ k: E& i/ V6 |  w$ w( E/ N
                      const long lNoOfColumns,) H, U& m) s8 T3 X, d, }' k  ~
                      _variant_t varValue[] )6 f5 o. T1 Y2 D+ L# M1 E! }. O
{
6 Z  |/ `- k  m  U    try' ^" S: j- V) D; _- x5 i) b
    {
; m+ x; d0 K7 ~# ^        // 参数变量
, f; R. }; r, g1 a        _variant_t l_vaIndex;+ V' b; J  ~/ X# x: h; S6 J
        l_vaIndex.vt = VT_I2;# }" ]  N) J1 e* S
6 ?  p2 K8 H- m6 _/ k
        // 循环取得列的值
- E( v3 k% Y2 l& o9 y/ K9 g/ G        for( long lIndex = 0; lIndex < lNoOfColumns; lIndex++ )8 o' Z# ?! P  p; ^
        {
3 k+ f! p/ U( B            l_vaIndex.iVal = lIndex;6 a$ Y4 D8 K$ h8 f( G
, V; M1 m: U! D
            // 取得字段值
& `0 J' z/ @9 t' v- G/ g- Q            varValue[lIndex] = ptrRs->Fields->GetItem(l_vaIndex)->Value;. k; o/ j% U3 a$ b- Z
        }
7 t9 G3 [) \/ B/ v, U# ]        return S_OK;
5 p; a, Q8 G7 X% n- Q    }3 A8 O2 i1 N( f6 m: t/ D* i( u
    catch( _com_error & a_pComError )- l# T3 x8 U$ J& \
    {
) F" l3 N1 P/ S$ k        …. // 错误处理
$ N% G7 F7 {, H7 T        return E_UNEXPECTED;
/ s& L- g; x$ B6 A    }
+ {4 |2 d% Z- w+ ?; R2 T7 I6 P4 D    catch(...)" |* Y7 D5 H% x  [: N/ b) L
    {
$ P/ R# l, Y( I( z        …. // 错误处理
% ^; d/ m3 t. Y- L& @* _        return E_UNEXPECTED;
' [3 b6 Q+ ?0 F) `1 j& n    }
7 R* s0 b7 e  Q}
$ y  R, G3 {# O) J1 j# S/ |) A' f. ?3 \0 V
! U1 m0 {) V6 Q7 L& n8 ~  O
7.出错情况下错误信息的取得
  T4 h# R3 o& Y; X6 ?
  Q9 |, X8 _' B! u' ]$ {; k: Mvoid ErrorFunc( _com_error &pComError, _ConnectionPtr ptrConn );
8 S, A8 A+ Q' R2 V5 [# N{
) J5 ~, P1 P; h) Y- ^    // COM 错误取得
/ j: [. x. q. D: _    // 当执行COM功能的时候,如果出错,可以捕捉到_com_error的异常+ A, D0 {2 `8 l6 o, \' m
    char lpComErrorStr512];
2 M1 P2 ~; m+ }* ]/ k6 z% {# R+ |0 v) W8 \
    sprintf( lpComErrorStr512," |: T( N  w0 ^
             "ErrorCode = %08lx \ Error Message = %s \ Source = %s \ Description = %s ",% |( @- s- d. N* g0 j! i
             pComError.Error(),                  // 错误编号
3 R7 M4 I8 c) }( v) P" E+ P             pComError.ErrorMessage(),           // 错误信息
; i( Y- f+ k# L! r; @, a             (LPCSTR) pComError.Source(),        // 错误源3 z, \+ p8 U2 h0 f: Z" c& O
             (LPCSTR) pComError.Description() ); // 错误描述# n) {3 ^& u$ F& p* U
- B7 _7 M% h$ s  ^3 m; P$ K/ k
    // 通过上面的代码我们可以看出,_com_error对象中可以得到COM所有出错的信息4 O/ G+ M# q( }4 \1 Q5 p
    // ADO错误取得
+ I2 J/ e& z! e+ g3 v6 `: V2 s$ E1 v
1 n4 c0 w- A" I$ P6 S    ErrorPtr pErr = NULL;
/ u) ^% q) I! G. ~4 l4 `8 A) w    if( (ptrConn ->Errors->Count) > 0)
0 T* H1 Z0 T9 U' w& W% p    {5 L2 a: l  F/ n
        long nCount = ptrConn ->Errors->Count;2 n2 R9 C' n, f' W
        for( long i = 0; i < nCount; i++ )  Z! k6 R! j$ z! ~, j
        {
$ s  X% ]8 v. D4 G) w            pErr = a_pConnPtr->Errors->GetItem(i);& I) J* ~% i. }) k" }( L

$ B; F- _$ M! ?' V: t; n% r            char l_pchErrorString[512];
- X, J/ H6 Y; k$ L1 F% A' F2 y) t            sprintf( l_pchErrorString,"Error:\n Error number: %x\t%s",
! \# ^+ c6 K( k                     pErr->Number,         // 错误编号
3 m3 H) `# G$ M% O2 m' G9 I                     pErr->Description );  // 错误描述" y/ V( T2 B2 H0 F
        }
, \" O) h) ?& S% O1 H! r+ \' t# q    }0 `, s1 e! ?' i; T2 C
* O9 `0 s4 a+ b4 u* l' W
    // ADO 处理出错的情况下, 在connection对象里面都有记录,可以通过访问% M5 ~+ e- Z+ a3 N, Z5 J3 u8 H) @
    // connection 对象取得错误编号和错误信息。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2025-8-9 04:25 , Processed in 0.034549 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表