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

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

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

/ e+ t# g! D& X2 U1、 用import导入ADO 的 COM 文件msado15.dll
2 q7 x1 j# `, J2 ^1 q. @; }; F6 K6 G1 P6 ?, J
例如:) |* w: y! P. l. |
8 o' O( \- c; K: g
  #import "C:\Program Files\Common Files\System\ADO\msado15.dll"\
/ A$ x& C$ X) Y, y8 G9 T
% ^  P0 i# t$ I5 p   no_namespace% \* e' c  H6 _; a! j3 F7 x# S

; `1 e( U! P2 }
6 x* U5 e. }- ]* q, P( {& N2、COM 使用时初始化9 z+ Q8 K- A- O3 K& d

' x( V6 `, \' o' i$ PHRESULT ComInit()
$ u. e9 G6 I: J1 u- r1 x6 Z& g{ % D) Z' X) M7 R- E1 h/ H4 [8 H
    HRESULT hr = S_OK;             // 默认返回值# \' A/ D0 O8 M. O! R
    if FAILED(CoInitialize(NULL))  // COM 初始化调用4 s/ B5 u9 O2 s3 q3 |
    {8 b" L% [3 ?" O
        CoUninitialize();
/ [. A, |1 B' P4 |0 Q& S  q4 A" l        hr = E_UNEXPECTED;0 K+ y. s/ P* K" A1 s9 I3 c" I
    }
/ t3 }; }/ n7 Y' F    return hr;
6 q0 ]- Q% \3 J& C' x8 T}( i" b0 M. n7 @9 ~/ G$ x5 c
6 J5 C1 B" w9 R" H# D

5 R8 j7 W3 q! q% z3、建立数据库连接
8 N3 J) a. x2 M2 J% Y: V) W1 ]7 t5 F  s$ f3 f* |
HRESULT ConnectToDB( LPSTR pUserId ,                    // 用户名) J  p7 _4 s& A+ c8 M/ S6 _
                     LPSTR pConnString,                 // 连接字串 8 e) L6 v2 V% t5 o: @: w0 b' O/ V
                     LPSTR pUserPassword ,              // 用户密码
: ]' @3 I& i, M0 b                     ConnectOptionEnum ConnectOption )  // 连接参数) l0 Z  E2 a6 O. _. f/ x
{
8 ]" Y$ I9 C' ~: ^' o3 m
3 U( I* D9 T. B$ D    HRESULT hr = S_OK;        // 默认返回值8 B" _# B. D3 _. N. n
    _ConnectionPtr ptrConn;   // 定义Connection对象% Q6 x9 m; g( f: B  ]
: P' N, @! e- x" h( `  B7 a$ l! ]& ~
    try
9 X: s3 N/ H2 Z    {
' u* {9 T5 Y9 m        // 创建一个连接实体; b4 u* Y8 e) x0 u! d7 Q' A
        hr = ptrConn.CreateInstance( __uuidof(Connection) );
' ^9 Z* K+ e; z# [* u$ `6 i1 G" _" y# ^1 g: _+ Q
        // 设定连接等待的最大秒数,默认是15秒
  Z5 P, ^8 Y0 X( U        ptrConn->ConnectionTimeout = 20. O/ |% ]- c  s7 Q& p& m7 ]
9 j" n% h; F+ p/ b6 r4 O% s
        // 打开连接* q- `9 {9 u) n  J2 s3 D
        hr = ptrConn->Open( pConnString, pUserId, pUserPassword, ConnectOption );5 z+ n+ x3 g  V4 [
        return hr;& Z3 E; l1 b: n3 {, q6 o8 k8 K7 E
    }& g0 s& ^; _" j  A3 [' f0 H4 r
    catch( _com_error & pComError )5 L+ K, @8 G! P
    {4 m# P* Y6 b2 `: B9 e8 I7 u; d
        …… // 错误处理. v+ \) _4 z0 N0 l" i# V$ B
        return E_UNEXPECTED;
  V; r# V8 Y5 m    }+ d: R3 w# m2 F, w+ |% i3 ^% U
}
; ]) @3 U% n+ I) g
# K, {' ]/ a3 m1 \2 p0 U
* I# _2 B' X8 d& ?9 L( ]4.执行一个SQL 查询,得到数据集(recordset)
" U) k6 H/ @3 {9 R/ R: k: w8 {' t8 \/ J
_RecordsetPtr GetRecordSet( LPSTR strSql, _ConnectionPtr ptrConn )) y2 O) N/ \  a% b' a# Y
{' N7 _% v& \: c) i
    try
# B+ N/ G4 ]" p. u    {$ j' @/ u2 \' c
        RecordsetPtr ptrRS; // recordset 对象
/ s5 \0 K7 O; `. ^) N  ]6 }% q: T, [' Z# X" I( `
        // 创建recordset 对象实体$ y3 s& Q' \, H! u; ^
        ptrRS.CreateInstance( __uuidof(Recordset) );
% n. _/ R6 w' D! d# Z" K' w, T        ptrRS->Open( strSql, ptrConn.GetInterfacePtr(), adOpenForwardOnly, ( P* `( V( X3 i' ?5 @: M
adLockUnspecified, adCmdText );8 k, T- j8 t8 J7 b7 M$ D. h

/ p) s4 `9 c8 p/ H2 e# t4 s        或者
  g- E0 f3 z, h8 v        ptrRS = ptrConn ->Execute( m_ strSql,NULL, adCmdText );+ z" V0 L+ V* N& @& J
        return ptrRS;
) H, Z# j9 ^4 i% y8 H7 B    }
  h1 p/ z# ?" {+ u% w    catch( _com_error & a_pComError )+ R5 ]. t, ?- B# u  c/ i8 m
    {
* b- t' L1 q: b0 ?- T. M6 Z- I        ….// 错误处理4 z' ^) N2 z( I3 R' t2 G& ]4 c" z6 r
        return NULL;
1 i: y% q! C, ^( F1 g    }
( K' u! j1 _2 b2 ]}
- q! b0 D( b, x2 r7 d
0 ?3 b5 H- U: Z# p# B1 e
, @( Q9 h& S) a2 ~5.通过数据集(recordset)得到列的名称/ _& e* y8 n! g

8 T, p3 i* b5 pHRESULT GetColumnNames( _RecordsetPtr ptrRs,        // recordset 对象$ l5 `5 x) ^3 Y8 l# W- ~" p, g
                        char strColNames[][255],1 M. _5 V4 B/ v- T- n( m
                        DataTypeEnum iColTypes[] )
* r. _$ D+ R8 q6 l- c( x{
! W" T% i# j, ]- t. v    try
8 E4 G0 ?$ `5 O    { // 参数变量
; T0 E( j. c4 y  R1 P( l' Q        _variant_t l_vaIndex;3 s6 u$ s- V' a2 \$ L0 P
' r8 @9 ^: T8 H5 i/ L/ U
        l_vaIndex.vt = VT_I2;
' m) o$ q  N2 B5 v* j; v! {- P0 ]2 g, P) ], H0 M/ U& s2 ^* P8 T
        // COLUMNS总数
, A9 i% X* S! U- f0 G1 V" j4 H        long lColCount;
/ B' b7 S* ]/ @( ?+ J) J" C1 ?0 r  z
        lColCount = ptrRs ->Fields->Count;
8 ?1 b. Q) B  k7 k" n& M, u% J/ t# R7 R# R7 p5 i! y  v
        // 循环取得列的属性和名称
4 [5 _* R- m3 {' m        for( int iIndex = 0 ; iIndex < lColCount; iIndex++ )
3 o; q, f. N9 n0 X: [( q/ ]3 P1 n        {7 G: z% ]1 h" i& m
            l_vaIndex.iVal = iIndex; // 设置循环索引
1 a! g  q' C% [" z0 O0 W- _+ V! E
* i6 t7 }2 q8 U7 r            // 取得字段名称
& G4 B1 Q* i( H" Z) @            sprintf(strColNames[iIndex], "%s", (LPSTR)ptrRs ->Fields->GetItem(l_vaIndex)->Name);
/ e' P5 m5 m& J) ^. n& t
) A1 Z/ Z) c- G! L            // 取得字段属性2 X3 v, |5 q& w0 `4 H( z
            iColTypes = ptrRs ->Fields->GetItem(l_vaIndex)->Type;
2 h$ n# B# S; _: D        }
  o9 O5 C+ @* O. y- I( n( m        return S_OK;; Z6 d0 w. [+ I3 m: w
    }
$ \0 ]& v$ A9 j    catch( _com_error & a_pComError )1 H* u& ^2 u4 k: W
    {
5 |0 }- D2 c/ n0 p& f& n        …. // 错误处理) r3 |% g* j7 b1 f7 \  V! p: G
        return E_UNEXPECTED;$ w. b% U) v; x8 o) v; J) D1 ]
    }6 ^# B( Y* x7 n- ~" s$ b# s( M
    catch(...)& X$ z% k$ D5 l; k. [
    {8 `: k$ }9 j& A# k! h9 V: G
        …. // 错误处理
) T, R( X$ u: h1 L        return E_UNEXPECTED;' }! \6 {4 G$ U% K( b) E) J
    }
: P, Y$ i8 f+ z% }}6 Q7 Q: W. ~7 U+ X- m

4 T1 f( |: G+ q  n
4 B3 J' f( G6 |6.通过数据集(recordset)得到当前行记录
' ?$ G7 @1 F3 e, l. B! t7 F+ P: Y1 @; p: W
HRESULT getOneRecord( _RecordsetPtr ptrRs,
1 J& [3 b( t+ T5 r! }) j                      const long lNoOfColumns,
) J8 B! V7 D9 l                      _variant_t varValue[] )" R7 D) Q. Z: [4 S" @2 e0 o
{: r* [+ y# W  {8 o: c& A$ t
    try- {2 |* o5 g5 P1 i0 ~: \  e
    {
2 A6 F5 }( P: G        // 参数变量
7 N7 `" F) h; j! u; S        _variant_t l_vaIndex;
! p/ Z; b4 g0 v6 D        l_vaIndex.vt = VT_I2;2 B' \6 P0 m. h- H$ m0 H
! e% \4 W# n2 ?0 M2 ^& d
        // 循环取得列的值0 L/ F5 U  [; C' d7 P! T
        for( long lIndex = 0; lIndex < lNoOfColumns; lIndex++ )5 t8 a9 z; P8 o- H2 j$ S8 c
        {
( H' f! o# j1 l/ c6 b* e2 O            l_vaIndex.iVal = lIndex;! e' x; s2 k  ^9 Q- D
5 `3 S# }; Y2 G. Q, R2 p
            // 取得字段值6 M2 O+ ~$ Y! w
            varValue[lIndex] = ptrRs->Fields->GetItem(l_vaIndex)->Value;
( b* Y  N1 s/ D9 {. R0 I        }
7 z+ z; |- p1 J        return S_OK;1 j. r2 ~% J/ V' h; G
    }
6 ?$ _5 A( a' k2 M4 Z    catch( _com_error & a_pComError )# ^) w8 G; B, a3 F6 L% S, g- z. G
    {
3 D/ q8 V1 G' e3 K9 }        …. // 错误处理3 a! `8 U  u% i; r& u5 ]. x
        return E_UNEXPECTED;
( ]+ J( B2 P& f# a0 R" f  j    }* W( S5 G$ V. a3 I' m* p
    catch(...)" J5 k3 t" P" e8 N7 P  U
    {
' m4 j. C1 ?1 k" K: t7 Y& i4 s  E        …. // 错误处理
! S, @9 }+ t5 B" v        return E_UNEXPECTED;
% w/ A& e$ P) u2 Q) ^3 F    }% Y4 [' A8 T4 U; B' w2 c1 U! v
}: a, y; c+ n8 n
, I. f- i# f% {2 O- b' m

! _9 Y8 F2 y5 o7.出错情况下错误信息的取得
7 j3 U& L( d" |+ R; _  q
( |# v3 n, I# `2 vvoid ErrorFunc( _com_error &pComError, _ConnectionPtr ptrConn );
. ~( Y5 z. C; {4 f5 W8 N{
4 Z$ l( B, C2 D& ]) W    // COM 错误取得! k6 G1 o0 M+ w; _7 f8 Y% z
    // 当执行COM功能的时候,如果出错,可以捕捉到_com_error的异常" F* i# w9 e; s
    char lpComErrorStr512];8 v: q: e* a! f* A0 N% d  j

; I; y6 ^) ]6 p3 Z, ]    sprintf( lpComErrorStr512,. G3 m1 @6 @$ H* A' j) Z6 U
             "ErrorCode = %08lx \ Error Message = %s \ Source = %s \ Description = %s ",
! m/ i& E% }0 f' D, ^             pComError.Error(),                  // 错误编号
) ^6 _% x( X7 m3 {             pComError.ErrorMessage(),           // 错误信息
+ O7 K' x3 s# p: ?1 P2 U4 X             (LPCSTR) pComError.Source(),        // 错误源* r; |! d3 s2 V: W: c
             (LPCSTR) pComError.Description() ); // 错误描述( e1 ]; P; \# ~' y2 l4 \- L

$ |; A! \8 \& N2 }6 x+ B6 P, F    // 通过上面的代码我们可以看出,_com_error对象中可以得到COM所有出错的信息
( ]' [) e/ c* p  R- j/ T. o    // ADO错误取得- x" R7 d+ d+ X% A; F

7 R3 a: G0 l. [0 d- t! A, {, m    ErrorPtr pErr = NULL;
. L9 G* x; A+ \* w5 `. P    if( (ptrConn ->Errors->Count) > 0)
# Y4 a4 a% e7 M9 k    {( J# X8 m+ r6 U- O; u% f
        long nCount = ptrConn ->Errors->Count;$ k0 Y; y  W; e/ e9 I
        for( long i = 0; i < nCount; i++ )
/ k' }0 M& O0 [( E: U' ~        {* B" c, o5 g, I+ \
            pErr = a_pConnPtr->Errors->GetItem(i);' \9 v9 A  Y5 g! r3 L

# |/ r4 }8 q9 N' c            char l_pchErrorString[512];
: U! R/ c( y2 s$ Q2 e9 @$ o            sprintf( l_pchErrorString,"Error:\n Error number: %x\t%s",
7 p  ]- {) X0 I! K" ^! [                     pErr->Number,         // 错误编号7 S# b- g& S7 |7 c
                     pErr->Description );  // 错误描述
$ I. I, i3 V' e* \        }
# Z( h7 H6 N& |" C    }& s5 i7 o$ T  {$ d; K4 M9 Z

% V/ [/ L! J6 Z* B) x" r    // ADO 处理出错的情况下, 在connection对象里面都有记录,可以通过访问
8 O( j5 m! y* ^3 ~    // connection 对象取得错误编号和错误信息。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 10:35 , Processed in 0.018092 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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