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

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

[复制链接]
发表于 2004-1-31 18:14:29 | 显示全部楼层 |阅读模式
  对于在WINDOWS上编写数据库程序的程序员来说,ActiveX Data Objects (ADO) 是最常使用的技术了,通过ADO可以简单的实现数据库的连接以及数据访问。但是在VC++中使用ADO时,却因为是使用COM的方式来调用,常常出现一些系统无法编译通过,或使用中程序非法出错的问题,在这里想大概介绍一下VC++中调用ADO的常用方法。
; @# J* d# v0 R2 |7 L
$ h! R% _) N, b# J7 @1、 用import导入ADO 的 COM 文件msado15.dll
& K& d6 e) D/ {$ i/ ]% y2 F1 X' s; @' X) S5 x+ _- u+ ?0 v8 b
例如:' J) ~4 Z( Z4 N( F; ^3 P
$ f1 H. l+ k( w& j
  #import "C:\Program Files\Common Files\System\ADO\msado15.dll"\$ s: n( _% ^# r6 N. ?. ^9 [
: R) |. }. q% |. `6 W! K& S
   no_namespace3 H+ T" i* @5 m
$ N7 ?# Q; y9 Y6 V
; u  E% t4 R% [
2、COM 使用时初始化
% m3 @0 ]" e( B0 @- D  v+ T+ b+ Q* g
HRESULT ComInit()
+ j( a7 ?1 x7 R" ~' `/ n* H# N{ ! m0 L% q) d0 Y2 j3 d
    HRESULT hr = S_OK;             // 默认返回值' a. |( z# R" B6 e  ~' J& C
    if FAILED(CoInitialize(NULL))  // COM 初始化调用
8 }0 Z- H* C. @' B1 L    {
  U7 F; g; Y- Y        CoUninitialize();
. h0 o6 B( K. l. X/ U( N        hr = E_UNEXPECTED;5 h, D5 `) z6 V9 H
    }
7 ~8 Q) B2 z4 T/ \    return hr;
$ D7 x% p! R' |" K' L}
2 p) e7 |5 e2 K, f$ R
1 d. _# a' }4 i% n7 \/ a
+ k% r8 Y* A9 j8 Z* `: S9 \* b3、建立数据库连接+ O+ J  _8 q! j

+ C! T' }) ?( Y& KHRESULT ConnectToDB( LPSTR pUserId ,                    // 用户名: l1 k5 w! I+ t$ v5 M/ o# i
                     LPSTR pConnString,                 // 连接字串   ]+ p6 n  |2 t0 k( Z. U7 q. B
                     LPSTR pUserPassword ,              // 用户密码/ P4 Y4 F6 J0 R$ K" L3 I
                     ConnectOptionEnum ConnectOption )  // 连接参数
6 d. S' o* q" x( K( \{
' o! p/ z5 a+ U# e- J
5 K* W' K4 Z/ h    HRESULT hr = S_OK;        // 默认返回值$ Q3 y, t3 s7 G; T
    _ConnectionPtr ptrConn;   // 定义Connection对象9 X- I: g' `( X$ w

% I& I/ f8 F  b5 v2 }4 r    try
% G% H8 p- }/ e0 f    {4 @# P  Q5 E' A' z
        // 创建一个连接实体. T' z1 r- O: `& h6 Z. Y' V$ H9 v
        hr = ptrConn.CreateInstance( __uuidof(Connection) );- T2 s# B) E; o* `9 ~
: [( g5 \1 k8 w, u7 X1 R, Z
        // 设定连接等待的最大秒数,默认是15秒0 l) r- |# y& m) o$ f$ _0 U: g
        ptrConn->ConnectionTimeout = 20& y: m: l2 \5 Z0 ]/ b) ]) b9 L  A

, j: ?* G* R  U        // 打开连接1 }5 [3 G7 O* P- }
        hr = ptrConn->Open( pConnString, pUserId, pUserPassword, ConnectOption );
) @! C  Y2 A. H6 @, k" k. {! c: E        return hr;
' G0 ~& ?- U4 \: z2 x  o8 B    }
& q0 C5 m7 V6 _9 P5 F) o8 [8 f7 D& k    catch( _com_error & pComError )# S9 w1 n8 w! B3 |
    {
/ _' m; E; F3 D        …… // 错误处理
6 E( C( c6 n0 F( X        return E_UNEXPECTED;* @9 |9 Z) ?! U3 B# \
    }
  g# b2 O1 ?+ h( Y: z/ }}9 g* t% C) A* \) Y9 D, F
" k2 J% Q0 X, R( k0 k

# ^; ^4 n4 b6 E8 ^" @4.执行一个SQL 查询,得到数据集(recordset)
; ~# w* o/ K+ v  G6 E* r5 d+ N( m5 M0 I. @$ ]) ^; [$ ^. T
_RecordsetPtr GetRecordSet( LPSTR strSql, _ConnectionPtr ptrConn )
' F  \# z& L5 B" \) \# ~{0 [- `: \. l+ W1 ?( ]2 g1 ^
    try
5 P) i. J: v# K2 o* S1 {    {
( ^9 \' J& {: n* u/ H( W; A        RecordsetPtr ptrRS; // recordset 对象. `+ V8 J% I. L) V
- h0 v$ W" q0 u1 ]0 f& J7 v
        // 创建recordset 对象实体
# b. U  {- X/ `$ \        ptrRS.CreateInstance( __uuidof(Recordset) );
1 K: {0 S* l- X5 @2 l        ptrRS->Open( strSql, ptrConn.GetInterfacePtr(), adOpenForwardOnly,   G+ L$ U6 F" J, C. `$ B6 [7 m" |
adLockUnspecified, adCmdText );! [9 H7 ~- N, X! b, y

/ x5 ?; w8 D; J( V9 f0 E) \  o! L) }! y        或者& V# ~! |6 r3 w) T/ s! R3 F
        ptrRS = ptrConn ->Execute( m_ strSql,NULL, adCmdText );( A; N2 s- U( I! M0 X
        return ptrRS;% D7 @; J2 ~/ `% ?+ L( D5 x
    }- Q( E* d+ X! W0 ]: p
    catch( _com_error & a_pComError )
. w6 }9 I; R, O$ E; m. c6 i    {3 [9 X+ z7 ?9 t
        ….// 错误处理3 c* p( `! k7 Q: z
        return NULL;
, C- P5 X) ?5 }  ]    }3 V0 n& j. Q! w; f
}
, t# Z; u' C' `
, d& F) Z, Y' ]0 \/ b
" N" |* a0 K! k" g. r$ L- ^5.通过数据集(recordset)得到列的名称
  S4 H4 a5 o' }. u# x/ ^) J& N1 c6 s; L7 y6 b# d$ |2 p
HRESULT GetColumnNames( _RecordsetPtr ptrRs,        // recordset 对象$ t# Y; v5 p5 E1 c% d+ \
                        char strColNames[][255]," S* M3 d3 }. G
                        DataTypeEnum iColTypes[] )
& a& F* z" L* ], @+ W: y- o{
5 `4 x4 {: S/ E    try
  v: s. b- C& @5 ~1 c. u    { // 参数变量
! G$ G' d' ?# c1 i7 F6 x" |        _variant_t l_vaIndex;$ A2 V* R  N7 a0 G9 M! _& ?
" f; t) [/ E- y9 g$ }
        l_vaIndex.vt = VT_I2;
% g* b5 Z3 O9 F$ @% l' h/ f0 @1 ]  R9 u) `
        // COLUMNS总数! U/ e3 P1 h5 z, S
        long lColCount;
- [. U  d5 ^9 k5 @: a# Z  s+ B: }% C$ [  C8 j3 E
        lColCount = ptrRs ->Fields->Count;
  R) ^' H7 t& }: k& d
* _! y6 o4 h9 }$ d7 j        // 循环取得列的属性和名称7 Y1 O; w8 A- Y3 J! M% J: B: E% E
        for( int iIndex = 0 ; iIndex < lColCount; iIndex++ )
0 c- u, E4 T, h5 z! ^        {; G$ P- {& g7 H  b; P2 B+ u
            l_vaIndex.iVal = iIndex; // 设置循环索引# t- D; z# w. Q2 a

8 T6 g6 v0 C2 V4 v( y) [$ m: X* O            // 取得字段名称
1 S/ H1 j4 }: G1 U, Q. _# N/ z            sprintf(strColNames[iIndex], "%s", (LPSTR)ptrRs ->Fields->GetItem(l_vaIndex)->Name);, M4 C$ C. i! a% Z  o* W

" t& \3 @' O& n& Z* l: j9 b1 }            // 取得字段属性0 W4 \( v: f. A( [' ]
            iColTypes = ptrRs ->Fields->GetItem(l_vaIndex)->Type;
4 Y9 Y& p) x  L0 B) ~: S% R        }
' q1 M) I# V+ Y) L/ w0 s3 a9 @        return S_OK;
) D( @9 e# _+ y& e    }
% Q' }& P  Z) g) g) ]% B4 s+ k: |6 e    catch( _com_error & a_pComError )
) H# @4 o4 }; I7 a, a2 Q    {7 Z& Y; W1 m. X* Q* l2 }) |/ n) l
        …. // 错误处理9 `) R4 u1 j( a
        return E_UNEXPECTED;! j9 E$ n6 n( }; `
    }
& Y) t  U3 u7 E! N  E4 c    catch(...)
. Y- f" B& i# y) n    {- g7 x. J) X/ b5 f$ R1 }0 g( f9 R7 m
        …. // 错误处理3 x8 a  p+ C: b" W& T
        return E_UNEXPECTED;. B. [0 J8 y# n1 S! {
    }/ r, b9 A% ?( b! o% a& Z
}: h% \) \: q, X/ |0 V4 e2 H, f5 g* D
( x' y2 p$ t; J

# Z1 o+ _/ X0 p: E6.通过数据集(recordset)得到当前行记录1 f8 C% j+ G- G4 }# w

. A; w% `: e9 LHRESULT getOneRecord( _RecordsetPtr ptrRs,
; a# W* R7 g5 m' |& U+ k                      const long lNoOfColumns,: J% _- m+ M7 T, ^: C' b& _& p
                      _variant_t varValue[] )  d2 h* z( Y8 e  r
{8 g; ]/ N& Z8 a5 s! \
    try
9 L& F" @. P7 C* ~0 b' y    {1 V2 b/ U% V3 F2 q( S1 q
        // 参数变量. F4 H4 G' {6 A# N* }2 |- \  U
        _variant_t l_vaIndex;( l: q8 N! J4 b3 H, P0 z+ C6 Y
        l_vaIndex.vt = VT_I2;& B2 U% H0 S8 E; @# [4 q, B

6 B" x# G7 c& O! V! d        // 循环取得列的值6 ^' `  f) h& ?: }3 t. n* f& J
        for( long lIndex = 0; lIndex < lNoOfColumns; lIndex++ )5 t: ?- l6 Q8 p$ q/ ~6 A2 B
        { ) [! \3 |8 }% y" s4 S: P1 n8 N" t
            l_vaIndex.iVal = lIndex;
- B0 ^8 j( _: c- m- h) {6 {
, ~) @3 K, T" ?3 A            // 取得字段值" a. k4 x; v4 v2 a# P! x. B) K
            varValue[lIndex] = ptrRs->Fields->GetItem(l_vaIndex)->Value;% b& A! Z) k. i+ C0 a- [+ ^& t: q  s
        }
) g5 [- J. ]- }) z$ D7 Q6 L2 b        return S_OK;
+ j# w2 {+ l( ^) b0 s& C/ r, c8 p    }) b( T8 o) J2 k
    catch( _com_error & a_pComError )5 v( h; Q9 ?) `$ C% [/ E. w
    {
* C4 i+ s# {# W- p, i- z        …. // 错误处理
; c1 g! B: e- y2 d        return E_UNEXPECTED;9 J1 ]) o8 V& D' l- E, a7 e1 S8 Q! c
    }
4 B$ v" r; E* _  s# _5 }    catch(...). t* @. D) ~- F; z0 T; X( R
    {
) y; g- @" [* v; @% I4 P' A9 _        …. // 错误处理
# L: ^9 F$ R0 c. _" ^9 g; \        return E_UNEXPECTED;7 g$ Q5 U: a' s: W& ?
    }0 r) j) M2 a6 _4 P  R
}# ^4 m3 f+ U% V' b
3 C/ H/ Q! Y+ K& }) ~1 M
7 R/ K, O6 v0 Q5 I& B
7.出错情况下错误信息的取得
( P; l4 U3 n! S6 I9 j: z6 P2 M6 X2 q& U5 f* N
void ErrorFunc( _com_error &pComError, _ConnectionPtr ptrConn );- H6 B( f5 r0 ]/ H' w
{
" S* J6 T: [2 B- P) g9 ?4 U    // COM 错误取得  u8 m, ~- ^  C9 A* P+ [
    // 当执行COM功能的时候,如果出错,可以捕捉到_com_error的异常
$ B3 R$ F" D( @* x3 I    char lpComErrorStr512];5 e! R2 E( Q% v- p+ a4 i/ c) }

& Q: u7 ]% O) T/ u. e3 T) |    sprintf( lpComErrorStr512,( |" ^# N6 }3 I- {  @1 W
             "ErrorCode = %08lx \ Error Message = %s \ Source = %s \ Description = %s ",/ X8 d4 F0 E& R. y
             pComError.Error(),                  // 错误编号
: x- v1 T6 `4 z4 x! a4 R             pComError.ErrorMessage(),           // 错误信息9 {4 Z! h) e; A8 W% x
             (LPCSTR) pComError.Source(),        // 错误源
/ ^) |. I4 E0 x* v             (LPCSTR) pComError.Description() ); // 错误描述, W7 R1 s5 b3 G5 d8 D$ V

" d, \3 U% Q' z+ J+ ~+ T: e8 d    // 通过上面的代码我们可以看出,_com_error对象中可以得到COM所有出错的信息) b' A& V, {5 K, I
    // ADO错误取得
0 H- I! h7 E$ Z% ]
8 J0 Y9 ^' W  P3 u' ^' p0 k    ErrorPtr pErr = NULL;
( k( C. N/ b# J9 r7 }    if( (ptrConn ->Errors->Count) > 0)" o9 F2 X+ T  k9 N. ~
    {! C& ^! F( O2 t
        long nCount = ptrConn ->Errors->Count;
9 O- o6 E) C9 N1 ]; T        for( long i = 0; i < nCount; i++ ): m- D% T! Q# p: |, E- J1 r
        {
) ]+ L/ m% Q+ D9 h            pErr = a_pConnPtr->Errors->GetItem(i);$ ^) j# c& Q4 R. u
# T* N  G! v5 F
            char l_pchErrorString[512];& R7 p" l  b" ~, m' `6 P/ X0 ?
            sprintf( l_pchErrorString,"Error:\n Error number: %x\t%s",( ]7 D4 E5 P# f6 s
                     pErr->Number,         // 错误编号
7 ~3 o% t0 e. p& H                     pErr->Description );  // 错误描述
/ J1 ~# S; o7 n  R" Y; f2 |        }) T' p. @. t+ @( h( h! f& u
    }
+ h  d6 ]2 ~6 g% V0 D# F% l6 ^0 v! r1 c# y
    // ADO 处理出错的情况下, 在connection对象里面都有记录,可以通过访问" n" e& \% L7 R* u/ V
    // connection 对象取得错误编号和错误信息。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-29 20:05 , Processed in 0.020862 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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