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

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

[复制链接]
发表于 2004-1-31 18:14:29 | 显示全部楼层 |阅读模式
  对于在WINDOWS上编写数据库程序的程序员来说,ActiveX Data Objects (ADO) 是最常使用的技术了,通过ADO可以简单的实现数据库的连接以及数据访问。但是在VC++中使用ADO时,却因为是使用COM的方式来调用,常常出现一些系统无法编译通过,或使用中程序非法出错的问题,在这里想大概介绍一下VC++中调用ADO的常用方法。0 H, A* q. L6 d- J: C. M

) M1 Z( r, {- r8 p; w% e5 a1、 用import导入ADO 的 COM 文件msado15.dll1 e( Y8 W* K. K, [5 u5 F# E0 M
& F4 Z, N" B" g+ n
例如:
  U8 M. j( U' M5 N- k( }3 |; B! N3 ?2 {! m7 b
  #import "C:\Program Files\Common Files\System\ADO\msado15.dll"\
: e- a% m9 ^# B6 X
( z; N: t! w1 ~6 ~   no_namespace
) ^, T0 P7 N2 Y3 h9 F5 P% W6 {* n! P0 H! d

9 [# M) y1 ^) w  p3 K2、COM 使用时初始化6 g8 r5 B% I4 |5 X" ]

% d0 E- ?3 U/ i: _2 GHRESULT ComInit()
, K" ]/ I/ N6 z6 w{
% N& S1 d+ [0 d  c    HRESULT hr = S_OK;             // 默认返回值+ @1 Q; r6 a8 b: B- ]! u& ]
    if FAILED(CoInitialize(NULL))  // COM 初始化调用1 j5 D  s) p5 h( R) W0 `2 \1 [
    {
& M; u# ?6 P7 J% |8 ^) o. p2 b        CoUninitialize();) z# w) C" S1 n. m$ h0 w
        hr = E_UNEXPECTED;
" H0 D0 \+ e& h    }
& P/ Z! X0 r* G    return hr;
* ?6 f' X( t8 c! I}
+ [7 d6 ?  T" y: D2 @7 d: q
, D% v8 |3 \- R- F0 V1 z; {( N7 |8 Q- j% C# Q, n+ B
3、建立数据库连接/ ]1 s0 c6 g, R
' ]- T( T" d! E3 O
HRESULT ConnectToDB( LPSTR pUserId ,                    // 用户名9 E; Z3 Q% c, N5 j
                     LPSTR pConnString,                 // 连接字串
& C+ |! O  r' v0 `; q5 k# K  R! |. q) A                     LPSTR pUserPassword ,              // 用户密码$ ]' G& s/ c; p4 Q9 C) F
                     ConnectOptionEnum ConnectOption )  // 连接参数
  ?3 e) c* }3 a4 b) ]{
" ?* v0 A! i2 h% z: \+ Y( Q; ^; P! Y2 ^
    HRESULT hr = S_OK;        // 默认返回值) u4 b  a/ u6 L" D8 x* u
    _ConnectionPtr ptrConn;   // 定义Connection对象
; x7 ~" `* k. {( s+ z+ M; |7 V4 g0 ?9 F
    try
" F4 ?( Q4 o% {4 |; N% O! a( Y    {
# {& A/ F( ]: r        // 创建一个连接实体
" n( h  j8 T! T6 m( c$ y1 X        hr = ptrConn.CreateInstance( __uuidof(Connection) );
  F7 }! F7 x: [1 L3 k3 o% h8 s% j
. k+ P- q- d  v, d        // 设定连接等待的最大秒数,默认是15秒5 d2 I) J/ |# l2 \" y
        ptrConn->ConnectionTimeout = 20
/ z1 |7 I2 R* p& e
0 r8 ]3 i0 J; W/ q        // 打开连接
1 T( ~; l" w7 K  b$ ~2 t        hr = ptrConn->Open( pConnString, pUserId, pUserPassword, ConnectOption );
, I: z- ]  D3 b+ e7 f: p+ F. ?9 Y1 m        return hr;
- V- U0 a: u! y2 a' X: {    }# a3 i: {1 e: @' m5 e" I
    catch( _com_error & pComError )
* }# O' @5 \+ ~    {
2 V" ~7 M* Z8 {% I3 @        …… // 错误处理
% h5 Y# ?3 r. R2 U        return E_UNEXPECTED;
5 P. N; S9 b; [8 f5 p6 y: }    }
. z6 _! p# b1 O- u}
) Q; B- u+ ^9 a( @0 {" j9 Z% e$ i6 d- ^1 n
9 B# O4 ~( {* j% M
4.执行一个SQL 查询,得到数据集(recordset)
1 _' l5 W0 s: V6 j# z, z$ L
4 I2 R& ~  l3 R% q" U# W! J_RecordsetPtr GetRecordSet( LPSTR strSql, _ConnectionPtr ptrConn )
5 e- v; }* B3 Y/ A. E* S1 b{) z8 Y6 y7 x, g0 f: Z7 B3 N" |
    try( u9 ?: K0 v' W
    {
, u- H2 ?; w5 s& Y        RecordsetPtr ptrRS; // recordset 对象$ _! z/ _6 ^' [3 @" q

" V! k  Z& f* c, \* r% ]        // 创建recordset 对象实体
3 L0 y# G1 c+ p1 X6 h, x: G$ ]& S        ptrRS.CreateInstance( __uuidof(Recordset) );
/ {* W/ q9 e- Y& }        ptrRS->Open( strSql, ptrConn.GetInterfacePtr(), adOpenForwardOnly,
: i( d* L' _* b! KadLockUnspecified, adCmdText );/ O6 o7 j- q5 E5 n9 m

/ y+ G3 q9 B4 L        或者
4 W: p( D8 I& W0 T        ptrRS = ptrConn ->Execute( m_ strSql,NULL, adCmdText );& f' |& T1 q' @- e  M. J3 {  v
        return ptrRS;
; X& P3 ~% r5 z    }' E' L* O; H2 L2 Q+ G
    catch( _com_error & a_pComError )
7 F) N# X% h: Y+ j4 c/ ]    {/ `8 n2 o( ~4 {& U, s5 Z9 f
        ….// 错误处理
  s9 m% w& {; d2 n  w        return NULL;
! z, f2 t' E3 Z    }1 Z1 `% b& r2 p/ N% w& X
}4 A/ d1 B) j" D( ?

4 a. o) N, n4 b% f1 c* K. a" \6 P9 V- d, \% X2 a  D6 Z
5.通过数据集(recordset)得到列的名称
- H: B0 I$ N* t4 }; Z8 F6 b2 K) f- ~$ K
HRESULT GetColumnNames( _RecordsetPtr ptrRs,        // recordset 对象1 i- L  l5 `3 T: x
                        char strColNames[][255],
+ I- ]# ~5 W* Z" B8 S                        DataTypeEnum iColTypes[] )* L0 H- o& A% [' C0 p  ~
{9 _& P9 g/ X. i! J- b! q
    try
; P8 u5 P  `% Z+ z0 ?* V! x: m    { // 参数变量0 \$ O* S5 |! P, D3 q
        _variant_t l_vaIndex;
# o3 p! ^9 T) q& y
2 b  ~7 s1 \- c4 T- t; g2 C        l_vaIndex.vt = VT_I2;- ?- B7 L- b* E1 f
0 r# ]7 R+ T& d
        // COLUMNS总数
4 b! O! K$ _8 [7 Q3 d) `/ F7 @" d        long lColCount;; }% w/ z3 {  E, [

& L) o7 h4 l# e% w        lColCount = ptrRs ->Fields->Count;
* |) n( @. Q) |) ]( w# r# ]  O) S- F& S3 o3 F/ l  @8 B0 D
        // 循环取得列的属性和名称, Z8 _$ K% V# ]+ V( v  Z
        for( int iIndex = 0 ; iIndex < lColCount; iIndex++ )
8 }4 N" A/ L+ e$ @% |: S        {" F2 M! K/ Z( F' E( K( O, i" X: h
            l_vaIndex.iVal = iIndex; // 设置循环索引& P+ n$ }+ Q2 \) ^

* n8 R$ c" R: M1 }8 d            // 取得字段名称
; B; W+ c$ P3 y2 d0 d0 M; A            sprintf(strColNames[iIndex], "%s", (LPSTR)ptrRs ->Fields->GetItem(l_vaIndex)->Name);2 a5 }! U/ M( c2 L3 f
. [! @' {4 d: n/ d
            // 取得字段属性
; S3 c& V- l9 j            iColTypes = ptrRs ->Fields->GetItem(l_vaIndex)->Type;
3 D- P/ M: F! w( b        }$ l( U3 J- _/ e8 I9 [! ^& a
        return S_OK;
5 y4 [; f  k* C  H- Y2 T    }
/ n6 R& c! x3 w9 v# B' A9 ^1 _    catch( _com_error & a_pComError )' S' g. e- ?# y7 Z* c; G6 h
    {
1 I; }5 w' ]2 b3 b  z        …. // 错误处理5 y) C+ I! q$ w! f, A  n( B  n
        return E_UNEXPECTED;# w! _; ^) j, \
    }. u( h' q7 ?& E! u# ~* y+ Q- W% {7 e
    catch(...)
) d2 v. u" L- `7 z    {6 b- ]& l* t" S0 K- Y
        …. // 错误处理
( i- q* m+ w' [' @) a* n0 \/ A        return E_UNEXPECTED;
, N0 ^' I1 j% s+ s# s    }/ O/ M+ L( g/ ]" f* }  g+ `) A, Q  |
}* T! C4 f' f9 J* X# z# N4 \3 h

9 |$ |4 h2 ^9 V1 P6 n% u1 J+ N- d8 @" [. `5 m4 W
6.通过数据集(recordset)得到当前行记录% L5 j3 Q" C( o  c  d8 q
; ]: E1 q6 f' h- k( J. u, F
HRESULT getOneRecord( _RecordsetPtr ptrRs,, B1 o/ a8 Z* e7 G0 f
                      const long lNoOfColumns,
2 F% X) E0 O; e( M  z$ h) O0 V                      _variant_t varValue[] )
* K& s6 v. f  c5 V3 V{
6 \2 c( {% t# k4 u: V    try
, X5 H" o$ z  I0 T% D' m, U    {
2 Y( o# B3 f6 w& z        // 参数变量
6 n) J1 R9 y  ^8 g, C        _variant_t l_vaIndex;
) k/ u: H, x6 v, Q8 L        l_vaIndex.vt = VT_I2;9 t# ]3 A) x/ m

. v: K1 ?( D! D: S8 b        // 循环取得列的值4 {' e; l. z. Z% u# p1 u
        for( long lIndex = 0; lIndex < lNoOfColumns; lIndex++ )
. A# h$ d+ _- }/ H' e4 S8 z: `: A        {
6 Y8 l& K$ P; W/ G; h            l_vaIndex.iVal = lIndex;
- }- O* z2 e/ t7 w! \$ q+ z1 |. W* k+ x  U5 ~: _: ]& a
            // 取得字段值
+ L+ [! c2 ~# F0 @3 s3 p5 U) x  V            varValue[lIndex] = ptrRs->Fields->GetItem(l_vaIndex)->Value;" \3 s1 d. S' t4 ?& H2 `5 {# N, N
        }3 D  n( K, M0 i$ U
        return S_OK;8 J  q3 J3 K/ N1 m5 Y3 Z! k% Z9 f
    }
- ^) b7 f2 l+ A8 _. b" L    catch( _com_error & a_pComError )) k; h6 h9 A0 ~! U3 F9 t
    {
/ s+ A8 r8 M+ x9 e2 i3 [. S8 \& M        …. // 错误处理: V" w7 j) y+ T4 j" \* p
        return E_UNEXPECTED;0 V# |/ c$ o  m9 B/ u
    }
4 a' X$ e. ~& Y) {    catch(...)
1 h" g+ i) \; B3 w2 |    {0 v) |0 g3 S5 z* m5 Q
        …. // 错误处理% w( |0 M. @% T- s3 ~6 r
        return E_UNEXPECTED;. ?7 Y! d8 t  j8 c* \5 s4 g
    }. p: O9 t3 O' S0 Y
}9 N) W2 u; D% s7 f1 _/ s

) J6 p' x/ D/ K& Z; w# e6 r& `) G6 _) P0 J
7.出错情况下错误信息的取得: ^9 w: }9 X3 A% m9 B

0 v( m! J, d' w; N: Hvoid ErrorFunc( _com_error &pComError, _ConnectionPtr ptrConn );
9 D4 W& m% q8 u% b( M{
$ A  Q# X% H( ]0 h. S    // COM 错误取得
/ [- F: Y2 I" O4 H1 L$ j. j    // 当执行COM功能的时候,如果出错,可以捕捉到_com_error的异常
5 P) g' Y! m2 q8 w4 F, ]; q    char lpComErrorStr512];6 ]( W  f  _/ _1 Z6 [1 b
6 c' L4 g, Z+ {; }+ R
    sprintf( lpComErrorStr512,1 u9 i. v7 i2 \/ l2 p
             "ErrorCode = %08lx \ Error Message = %s \ Source = %s \ Description = %s ",0 Q6 m- L9 \( q  D7 M1 h% ]% |
             pComError.Error(),                  // 错误编号
$ e+ F$ B5 h; g. f7 P8 _' U             pComError.ErrorMessage(),           // 错误信息
8 A: F- R, D, G3 d; \             (LPCSTR) pComError.Source(),        // 错误源9 L3 Q9 z, G! q% b, B
             (LPCSTR) pComError.Description() ); // 错误描述
! t2 i# M2 d# u9 _% c$ u" ^4 F& ^6 w& X7 z/ s: q$ `. f3 y
    // 通过上面的代码我们可以看出,_com_error对象中可以得到COM所有出错的信息7 [. N$ X: w% W* g' E/ |
    // ADO错误取得/ J$ \( {3 S0 C

; K! V: C& f1 I' ^$ A) x0 R    ErrorPtr pErr = NULL;. l2 p3 ?/ t' s0 p( g7 C( |9 N/ O
    if( (ptrConn ->Errors->Count) > 0), q. x% `. D3 H& ~# v, m) a0 w
    {0 @% y2 ^0 o- b( |. c
        long nCount = ptrConn ->Errors->Count;
% L$ m% O7 h/ ~! H. A        for( long i = 0; i < nCount; i++ )
8 m' D8 c6 Z5 Z' p4 K9 Z8 r( x        {
2 ]3 G  z6 l4 o# C( N: j            pErr = a_pConnPtr->Errors->GetItem(i);
! ?, _; h( s9 S, T' z' ^: z5 m4 P. S- }, P* Y0 \7 I
            char l_pchErrorString[512];
8 q% a% L9 [8 u) }' n: j# M, F5 Q            sprintf( l_pchErrorString,"Error:\n Error number: %x\t%s",! Z- Z7 z. |% ]
                     pErr->Number,         // 错误编号
  o3 r  d1 Z/ N9 D* B9 n                     pErr->Description );  // 错误描述
" e0 h$ \' w3 w. e' _        }4 m- U" R/ J( ~/ _$ W+ d
    }& j2 ~# G* o! ~

# q& P* c) G1 u7 J* K" E    // ADO 处理出错的情况下, 在connection对象里面都有记录,可以通过访问" B( b/ q: ^# w- e4 j& i9 m
    // connection 对象取得错误编号和错误信息。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-9-30 09:00 , Processed in 0.036235 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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