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

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

[复制链接]
发表于 2004-1-31 18:14:29 | 显示全部楼层 |阅读模式
  对于在WINDOWS上编写数据库程序的程序员来说,ActiveX Data Objects (ADO) 是最常使用的技术了,通过ADO可以简单的实现数据库的连接以及数据访问。但是在VC++中使用ADO时,却因为是使用COM的方式来调用,常常出现一些系统无法编译通过,或使用中程序非法出错的问题,在这里想大概介绍一下VC++中调用ADO的常用方法。1 J% ]" n! @: V& D1 _
; A1 \9 @! U8 Z6 j
1、 用import导入ADO 的 COM 文件msado15.dll
, J* M' B) A$ o$ A$ ~! N. Z5 g- J( e0 V" ?
例如:
# z( Z5 n: z% a$ _; M' r' s; A
+ A% E; W  g/ P! Z" S  #import "C:\Program Files\Common Files\System\ADO\msado15.dll"\7 @( C# ?$ I  \+ w0 F' A# q
4 c% t' u( k" w7 _; @% \
   no_namespace
9 c% T( Z# a% |2 ~5 Y' J5 j% w3 k. P8 J; V. L  j' r' y' [. ]
9 d& T7 ]9 W6 x- v5 b  \: @$ @7 J
2、COM 使用时初始化
) F3 s) {+ o3 t* u6 i; v
0 S7 ~5 `; |0 r: P8 FHRESULT ComInit()! D  p8 l, e9 ^" p, O
{ " x+ H+ z' x$ `. i3 P- t" L
    HRESULT hr = S_OK;             // 默认返回值
# |7 W- j: p+ h% c    if FAILED(CoInitialize(NULL))  // COM 初始化调用
( {. \$ e* g. Y* C! z9 L8 [    {3 w+ y9 D( D! O' ?9 _. t! L
        CoUninitialize();' e  I) k& P* ^: E/ c$ l4 C+ W
        hr = E_UNEXPECTED;
) D) {3 W- Y& ^/ \9 x* U    }( }+ k/ {/ X, T* Q/ M3 h
    return hr;! o9 X, }, p, j& r1 ^
}
0 j7 p: l; {$ R" K" r9 D  `( P4 T: i: x' V4 z3 D6 z" e) X# V
5 X1 @* Z! W& x( Z( M9 I* x: I9 n! l
3、建立数据库连接7 q. `. S, R: v8 A$ d% N
1 [$ {( N" j5 D
HRESULT ConnectToDB( LPSTR pUserId ,                    // 用户名
3 m/ S& Q* m/ x! C                     LPSTR pConnString,                 // 连接字串 ; j" @4 E" ]; o/ Z
                     LPSTR pUserPassword ,              // 用户密码2 K2 N% b5 s: B( m+ W
                     ConnectOptionEnum ConnectOption )  // 连接参数
# Q* D( e$ c3 F4 a2 m" ?- J{
7 p" s- e4 q2 O0 _' c. D; q
: ]" h& H7 _7 q5 ?4 \  C7 z    HRESULT hr = S_OK;        // 默认返回值
( B5 ~- H4 k. g6 t; G8 P* R/ [/ \$ P    _ConnectionPtr ptrConn;   // 定义Connection对象+ }$ B- F" l, G5 n; O. Y3 T

$ r2 f5 ?# A. I8 B6 e( r$ Y    try
* E, o" R. o' e    {$ X4 A8 g0 l- v, s; ?3 Q3 K
        // 创建一个连接实体0 P. D2 j$ ]7 x$ t- `  ?9 F1 B
        hr = ptrConn.CreateInstance( __uuidof(Connection) );
: G7 @. T. Y  S) m* N7 t) E# c- O/ W
        // 设定连接等待的最大秒数,默认是15秒
  R5 m) r: ]5 Z8 o! ]6 j0 g: B# c        ptrConn->ConnectionTimeout = 20
/ j+ B  F, \5 z( C! F* n! o
/ D% n1 z, k- X" S( F        // 打开连接
- P- T* U" i0 Z1 x7 j4 w0 D; k        hr = ptrConn->Open( pConnString, pUserId, pUserPassword, ConnectOption );* T! o+ U" E' X# P
        return hr;( M( ?0 a0 t8 d# y
    }
- M: p; t2 X2 P    catch( _com_error & pComError )
+ y$ V( n) g) p4 f% }6 Z0 e    {
7 \+ Z7 K6 \  o4 \        …… // 错误处理
4 I/ Y# C. m: S1 G7 @        return E_UNEXPECTED;- P# i3 }! i' A: A  i
    }* R0 Y6 y6 O1 Y6 g
}3 k3 F2 C5 @% w, {  h

7 c5 M1 s# w, [8 k# e! \
& v$ d# F/ B$ }5 R( Y4.执行一个SQL 查询,得到数据集(recordset)
/ a& t9 o1 t/ i4 S  D1 x5 b& m( s: A$ [/ i: y& g
_RecordsetPtr GetRecordSet( LPSTR strSql, _ConnectionPtr ptrConn )( o( s9 J) j! x8 }
{. h2 c0 C% S0 |  ]
    try
2 h. [3 }9 e8 P! a) z' K    {8 |8 ]# i) o- d
        RecordsetPtr ptrRS; // recordset 对象
  e$ C& X" L. \5 o4 P' T. s3 E; j& u; w* m/ z# D8 {
        // 创建recordset 对象实体
2 Z5 C- {' K# e9 e        ptrRS.CreateInstance( __uuidof(Recordset) );: Y. h" K: s( T! w
        ptrRS->Open( strSql, ptrConn.GetInterfacePtr(), adOpenForwardOnly, $ P6 s0 |9 z4 y9 l
adLockUnspecified, adCmdText );" R2 ]8 d9 r9 p" u, s- l5 y% {

* o0 u  m+ S7 _! c4 K8 `        或者: `  R- _( G$ C2 K1 x
        ptrRS = ptrConn ->Execute( m_ strSql,NULL, adCmdText );
1 @0 w$ [4 s4 G5 H8 W( y. b: j9 Z8 N        return ptrRS;
( H+ }+ t* ^2 z9 a    }7 R# S/ R5 f+ L- l% }- L+ c
    catch( _com_error & a_pComError )- @2 z" Q# O5 u. l4 j* L, {
    {
) l6 L1 [2 P: z* N) ^        ….// 错误处理+ i3 ^: S$ F, J0 N" R
        return NULL;
: G# _( c! m0 _/ p' F    }
7 e- f6 k& A/ a# X}
# f. u* u/ u& m% A3 [$ @* ]9 z' R1 ?& Y4 N; ?  }) C. R0 d
( Y5 _' k0 U$ I$ Z" g
5.通过数据集(recordset)得到列的名称
) q( U# e8 m4 p. Y! e9 f7 d7 l
* p. T1 h, m8 L4 [+ f3 iHRESULT GetColumnNames( _RecordsetPtr ptrRs,        // recordset 对象
0 r- I1 I3 }7 o! o1 X: \! z. P" {                        char strColNames[][255],
+ K3 t9 D* T& B  v, h$ \2 e                        DataTypeEnum iColTypes[] )3 R# e9 {$ a  w8 \8 Z: z. o; N
{
  S& y+ C2 m! N) T, P4 K    try
" Y# e7 n* f& l8 `  p) ~9 P0 ^    { // 参数变量3 V/ T5 f1 R2 i3 t' h5 e5 x+ G
        _variant_t l_vaIndex;
9 H5 N+ B; G' h% }( l' ?
7 D( E, r- M3 n' M% D# t' F1 X        l_vaIndex.vt = VT_I2;6 F! T& M. f  R3 R& w) U2 k" D

5 |/ i* A" R* a! i        // COLUMNS总数. z; _8 i8 c1 N4 U; y. x
        long lColCount;
6 M! K+ A0 ^6 r% y9 h, }5 q- H0 S  z3 C/ ]! S7 A
        lColCount = ptrRs ->Fields->Count;7 Q! s3 ?& W. a/ r

& {7 L/ h" ~8 g; `        // 循环取得列的属性和名称
/ |& Z2 G  G: V8 t% m% y+ s        for( int iIndex = 0 ; iIndex < lColCount; iIndex++ )0 `- e: ^; R) Z- {
        {
/ r3 E! q  j( X7 |1 @1 T            l_vaIndex.iVal = iIndex; // 设置循环索引6 k% l9 |* ~3 j9 e6 N9 w  l: L) J
1 z" G: \3 `3 u( V0 x& Z  n
            // 取得字段名称! L, u2 I. t1 k4 ?! F4 {, G
            sprintf(strColNames[iIndex], "%s", (LPSTR)ptrRs ->Fields->GetItem(l_vaIndex)->Name);/ u5 o& }. j  y7 h% [

. E4 \" ^- V1 K0 r  y" O9 o, s            // 取得字段属性: V$ A1 K5 W3 {1 g6 Y+ q) k
            iColTypes = ptrRs ->Fields->GetItem(l_vaIndex)->Type;
+ b) Q6 V  I: e% N. h* V        }
! l- D/ w/ q7 z* `8 ?# V        return S_OK;
1 a; h7 k7 {; Q% U* v& o9 Q    }
% u# G, Z* i9 @+ t  i. p% {    catch( _com_error & a_pComError )1 |' g0 x  y9 J0 N* d* a3 h) T
    {
" `$ _9 x# z1 ~( s  ?0 R5 {        …. // 错误处理3 @5 `! e* p0 l- H8 `+ ~
        return E_UNEXPECTED;, C- H) L! a( O& d' E
    }
: P" Q  ~, Y# s1 `+ v7 W    catch(...)
- k1 w3 q" e& G7 o$ Z) u" q  S/ O    {2 X) e% u1 ?9 i( Y1 S  i0 R* d
        …. // 错误处理
, x8 G$ g- C  I! b6 f" e        return E_UNEXPECTED;6 K5 Q7 Y1 A% l) l2 q2 t9 O
    }" \. v6 ~' k" H! t
}5 `5 P+ L- |7 |/ i  l1 D! @- w9 M+ T

2 t6 T) u6 q% w# x# }) F% c; k
! t; G+ l$ A1 a* p+ `6.通过数据集(recordset)得到当前行记录) f& J2 I9 g( r9 Z( _, r; U& k

+ D7 M  ]8 w$ g( mHRESULT getOneRecord( _RecordsetPtr ptrRs,
$ [. L1 g: T; ~' Q+ j                      const long lNoOfColumns,
; o( x; L% k, L* u                      _variant_t varValue[] )
: N2 H$ J/ S/ ]2 i  O% O* ?7 j{8 ~9 B4 I, k, U- K& [
    try. |5 i1 H& U4 y- F( p( c4 P
    {4 I7 b+ E6 t7 t
        // 参数变量5 Z; @3 F( a8 j1 N7 p
        _variant_t l_vaIndex;% m% U+ E5 x" J& s8 X" p# Y
        l_vaIndex.vt = VT_I2;
# l) C0 O* \3 P, o. z6 E" J- u
1 x$ `& S% Z* E3 X% _8 V        // 循环取得列的值, T5 ?7 |8 N) |  G  i4 w
        for( long lIndex = 0; lIndex < lNoOfColumns; lIndex++ )
, w. N: Z$ }  |5 u3 W. q        { ) ]+ D! A& y" W7 ~) ?: E  x
            l_vaIndex.iVal = lIndex;
4 f: V8 B* d7 c6 c3 o
+ B: h: w1 Z0 f) V            // 取得字段值% T  c# J# V- u. w
            varValue[lIndex] = ptrRs->Fields->GetItem(l_vaIndex)->Value;8 J4 t, i# ?- q; _& K7 A( R, D
        }! B) ~, m* R, Z  J3 T0 i: \
        return S_OK;
. [4 A$ }: F1 `- j: e    }
  x2 I) f) a4 s$ n5 o+ }    catch( _com_error & a_pComError )8 S: M( J+ j- E
    {) p7 D0 n2 z6 d0 s: L( R7 h) y3 ?
        …. // 错误处理
7 N* V7 a( ?7 o        return E_UNEXPECTED;) M1 w' M1 U$ O, ]& L8 l) ?0 m
    }
+ t! L, `0 _+ T% ]3 E    catch(...)
* L' \' O% R7 S. S. w- ~5 V+ [    {9 `. A. }8 b1 t. O7 d. f
        …. // 错误处理6 i* t' i5 H* j* }6 D0 r( l
        return E_UNEXPECTED;4 p. E( U$ x% Q& j
    }
. C1 F! G. l& Y1 N" E5 N}
2 W# |! i) x6 `
. ~6 x1 A4 O1 ?7 O- v, T  {2 U2 _+ ~% X4 E5 f
7.出错情况下错误信息的取得
. c3 c" o/ _  ^1 r: Y4 v4 |- I
& Z" r3 n! d. Y4 z/ M' @; T4 A2 Ovoid ErrorFunc( _com_error &pComError, _ConnectionPtr ptrConn );
' P, S! u* r( A' S6 R! H& |4 W{
- c! J6 r# F: f5 s    // COM 错误取得, X% F, H& u7 w4 X
    // 当执行COM功能的时候,如果出错,可以捕捉到_com_error的异常* W# Z: ?7 o' x
    char lpComErrorStr512];& M( F" z" h( W  i; q( J1 A

& D4 b) a4 d7 ?/ X8 f+ |, ?    sprintf( lpComErrorStr512,+ f% [$ f& O/ |  \9 x
             "ErrorCode = %08lx \ Error Message = %s \ Source = %s \ Description = %s ",
; d+ Q- z* P9 V9 V/ R             pComError.Error(),                  // 错误编号
( t1 U' ^$ y% q  f  J4 x; J9 h             pComError.ErrorMessage(),           // 错误信息7 U3 D7 U# d2 K2 A) o- r) F
             (LPCSTR) pComError.Source(),        // 错误源
$ s+ L! S. P4 A* v6 `7 M. X             (LPCSTR) pComError.Description() ); // 错误描述& p5 h" V% `% r& i* q0 w: N

- |- L$ G2 L8 V8 N' f2 b: ]    // 通过上面的代码我们可以看出,_com_error对象中可以得到COM所有出错的信息
" I1 l# m: `6 X% b/ d    // ADO错误取得  u: I" M, L$ K4 l( M! e) d: C& W
: W, x$ X. |% J
    ErrorPtr pErr = NULL;
2 E4 |! O: A  N8 I% I, F    if( (ptrConn ->Errors->Count) > 0)" _$ y% Z) [: I7 M& r' n$ N
    {
/ l4 }# I$ r& w0 C2 x# `' G        long nCount = ptrConn ->Errors->Count;
7 I& H" w% V" P6 w& N        for( long i = 0; i < nCount; i++ )# _" M. _$ Y: b% k4 P
        {
& q2 j1 m5 f" z3 l2 C# @            pErr = a_pConnPtr->Errors->GetItem(i);' o% J1 O$ u9 ]0 m# B

4 S& Z/ ]) D- P* I6 X& g            char l_pchErrorString[512];% ~+ v; O' r1 N$ r6 F* t2 S  B
            sprintf( l_pchErrorString,"Error:\n Error number: %x\t%s",$ p. p" X" K8 d: p( A7 K- q- D
                     pErr->Number,         // 错误编号
- M* j5 e. L( i8 v8 U; i6 M5 A                     pErr->Description );  // 错误描述! H; W" U! ^; E8 H! q* S: F
        }' G2 W% W. X& T8 p$ O3 V+ K- S
    }% i6 g) }' F  K( F" f; v

) m" M3 T7 n7 E8 c    // ADO 处理出错的情况下, 在connection对象里面都有记录,可以通过访问
$ F% U. \3 \  P    // connection 对象取得错误编号和错误信息。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-15 11:33 , Processed in 0.019577 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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