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

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

[复制链接]
发表于 2004-1-31 18:14:29 | 显示全部楼层 |阅读模式
  对于在WINDOWS上编写数据库程序的程序员来说,ActiveX Data Objects (ADO) 是最常使用的技术了,通过ADO可以简单的实现数据库的连接以及数据访问。但是在VC++中使用ADO时,却因为是使用COM的方式来调用,常常出现一些系统无法编译通过,或使用中程序非法出错的问题,在这里想大概介绍一下VC++中调用ADO的常用方法。
( M& c- G1 H+ s1 u" Z$ b
  K8 h  k- J6 T, _1、 用import导入ADO 的 COM 文件msado15.dll
1 P' X2 X/ v0 k" M7 X3 h0 ~( q. R8 m* T+ _. ^7 V7 s
例如:. r7 E& n" D6 d$ l* K7 `6 d
, d* s( ?, |5 n5 S( W
  #import "C:\Program Files\Common Files\System\ADO\msado15.dll"\: b$ K( O6 T/ Y& Q7 F* w# t
: a2 @4 U8 _$ n8 l
   no_namespace
  i) d$ `" k, @1 V( D' n/ _2 t7 A7 z* z+ P; g# Q0 L5 c1 z

0 K" Y/ t& c, l4 K- b" f2、COM 使用时初始化
6 S0 g* d3 D& D: c0 b7 k4 N( r) J" l7 ]& M  Y# Q
HRESULT ComInit()
1 ?0 l% N: u% X$ Y, ~{ , s3 L: L% E  i* v. D# [
    HRESULT hr = S_OK;             // 默认返回值- W' B4 n* G% d
    if FAILED(CoInitialize(NULL))  // COM 初始化调用3 n9 {; z8 ~* c, T# Z6 t* U
    {+ Z& d/ o. M" s1 |, l
        CoUninitialize();4 F+ t# q" A8 D- z- s: }  ?% Q
        hr = E_UNEXPECTED;
  Y$ W& K4 {4 Q# {    }
! F  ^. z& j- Z- Q2 r' i    return hr;6 I, K2 r  S2 U0 X, ^0 ?7 A
}& U' {1 B+ R& P
% c. B5 E4 W4 }' _1 p- U! {; ~( ]2 L( e
- E, F+ g" G, l; c( c9 `8 p
3、建立数据库连接& r/ R. ^* I5 L2 U2 z

- \9 P. Q+ b9 `1 _# D5 s. m, hHRESULT ConnectToDB( LPSTR pUserId ,                    // 用户名
8 p. h6 |" r9 T. `* q                     LPSTR pConnString,                 // 连接字串 / b  }3 w" \" G5 b
                     LPSTR pUserPassword ,              // 用户密码
2 W2 c5 L1 t( r9 B8 W                     ConnectOptionEnum ConnectOption )  // 连接参数
* v* Z, Q' _6 T6 Z, Z7 A. K# ^{
1 |2 C% k9 H: J; t/ N# ^5 h# B3 u7 q$ u- Z7 d$ B/ P0 E
    HRESULT hr = S_OK;        // 默认返回值0 ~+ s: m9 X" a, |% I+ x$ p
    _ConnectionPtr ptrConn;   // 定义Connection对象; O; [7 w+ U  d9 S6 H9 @5 U' Y
4 F* z! z+ [8 S  E1 z
    try
/ S6 W2 c2 {  ?, h! o4 n& n    {
. s( g. E6 [0 j4 ?3 @        // 创建一个连接实体
8 |# w: o& K0 G        hr = ptrConn.CreateInstance( __uuidof(Connection) );+ a* l7 W. G1 C2 {# f0 k4 J9 O/ c
! F( a  b$ F& n, [" i2 E
        // 设定连接等待的最大秒数,默认是15秒
8 w5 W2 @5 \2 I6 M5 v: F- S/ b        ptrConn->ConnectionTimeout = 20
& l, l! R2 ?/ I' B* a6 ^7 D7 i, M8 n8 i4 A7 r$ [
        // 打开连接3 R; ?' E+ `7 J9 {9 G
        hr = ptrConn->Open( pConnString, pUserId, pUserPassword, ConnectOption );2 n7 x& m% r6 z0 T- J& h
        return hr;! j' L& d0 X) _8 I1 x" Q
    }% G* Y* ]+ p2 I! g( Z6 f
    catch( _com_error & pComError )* H1 ^" q* `5 d0 m
    {
1 C3 n* Q' T# Z% ~! n        …… // 错误处理
. W3 N' @. O' M& _        return E_UNEXPECTED;
1 G( m: t* R# p/ |* z    }
: B! j% b! v* |* ?}
  e5 B$ z9 J8 K( N- n
4 j3 d9 u! S8 E; C
6 |5 y2 B% W# @1 p4.执行一个SQL 查询,得到数据集(recordset)
6 m- w- @( F. U/ n  ?5 ]. T+ w- j7 d8 i6 y' e1 ]- o, D
_RecordsetPtr GetRecordSet( LPSTR strSql, _ConnectionPtr ptrConn )5 g0 d9 h7 I  M& M) Y/ ~; s$ b
{& d& ?: J+ E! d/ z1 _+ W
    try+ Z5 O, ]2 p- s! ]) A1 y
    {7 T* h$ K& ?) p3 F9 G$ ?
        RecordsetPtr ptrRS; // recordset 对象
. u: ~$ p' ^# f5 j% W/ D, ?  Y! P6 V2 N) E5 s( {7 T  K$ K; X( [
        // 创建recordset 对象实体
0 x. [& f; u8 j6 B        ptrRS.CreateInstance( __uuidof(Recordset) );6 Y: W7 I/ S; w( `8 c* X
        ptrRS->Open( strSql, ptrConn.GetInterfacePtr(), adOpenForwardOnly, ( s; o! y. d) H" z
adLockUnspecified, adCmdText );
: }9 r0 H' Z* d  v: q8 n+ c
# q- p  W$ a9 z' P. R# F$ J        或者
0 C0 K( ?" A7 X8 U& R7 s1 x# P        ptrRS = ptrConn ->Execute( m_ strSql,NULL, adCmdText );
9 f. B( a9 B% Q) f2 d        return ptrRS;
' J6 l- i" x& B( y" Q    }
; K" b, K' O+ [8 n+ i    catch( _com_error & a_pComError )
' ]; J, ?8 [( l    {9 l: M/ `1 N5 z
        ….// 错误处理
7 n$ v) e* p( Q9 V9 n. U        return NULL;* L1 y. N  d. I3 ^
    }: f7 U" @% D3 a! Q( I' p3 j
}
2 g& e" N0 ]% {% h' H" h% h$ p9 L' ^/ J& w% [) x# }; n
0 a) j( @& b; @( {" {
5.通过数据集(recordset)得到列的名称& g, d, V( Q8 R# x
  f9 E0 H1 X# g. i9 d
HRESULT GetColumnNames( _RecordsetPtr ptrRs,        // recordset 对象0 J* O" n, O6 V* _
                        char strColNames[][255],7 ^0 n$ `7 U. d
                        DataTypeEnum iColTypes[] )
  j% L% }0 R4 ~$ j* F6 l{
, x+ ?, t0 H8 q; z" ^) M    try9 j! I: {# |: J
    { // 参数变量
+ V6 r$ [' l! b# H( }6 Q7 y        _variant_t l_vaIndex;' R7 b+ f8 R% X2 {/ W0 N! {
% m; Z& _+ ~9 \! M" }
        l_vaIndex.vt = VT_I2;
) Z  {% y" w% g' l5 n- l6 u$ J7 \  F3 v) r4 ]  Y' w! g2 i' G
        // COLUMNS总数( p& o$ Q2 Z8 N& l; B& n& h8 I7 O% A) F
        long lColCount;7 ]  C2 c% H6 C6 w3 i  `

% a2 Y) k5 M) G) o3 m3 r. c7 P        lColCount = ptrRs ->Fields->Count;9 A0 z" c: Z* @$ n! f' h% b& `
: c" O( u6 \% O' ~+ J9 {( R
        // 循环取得列的属性和名称
' D, ^% A4 g: X" E+ N: {6 m        for( int iIndex = 0 ; iIndex < lColCount; iIndex++ )  M8 J1 \+ \7 L% q  `' v
        {, g( O) P% Y$ \  L- O) ^8 o
            l_vaIndex.iVal = iIndex; // 设置循环索引
" N7 C0 H7 e9 n) A4 h  P% D: e% H5 T  `8 Z, u
            // 取得字段名称- m* H* o" D! Z6 _
            sprintf(strColNames[iIndex], "%s", (LPSTR)ptrRs ->Fields->GetItem(l_vaIndex)->Name);: N: o" S  t. _9 f

$ J  \2 ]( `/ q% e" l, k            // 取得字段属性6 t: A1 @$ w/ V' ]+ N
            iColTypes = ptrRs ->Fields->GetItem(l_vaIndex)->Type;
( v' I  k) ]* e3 H6 [, m3 }        }7 M! F, r3 t9 h3 E2 u" {! E
        return S_OK;
, E3 T( M2 H' z8 [, ]& V    }$ {7 I/ z! Z) {: N
    catch( _com_error & a_pComError )+ m8 v/ _# a; k- }# s
    {* i- F' i( W" k' Z
        …. // 错误处理- H& c7 A5 P1 v7 R# @
        return E_UNEXPECTED;4 r% A; {" q/ ]7 O  n
    }4 p& Y& v# `! L% W) ?, b/ o
    catch(...)  P; I0 O& D# A$ y
    {
0 U/ M7 y5 k7 I        …. // 错误处理
" L& {& V" V5 ?* R4 [        return E_UNEXPECTED;( z! J; j) x1 I
    }# N* h) X) [( a$ V5 R; j4 O
}! P) f& e; f" S9 c$ d

: M0 V$ u% r, x9 h3 i
% P) P8 t. Q7 }5 K- \6.通过数据集(recordset)得到当前行记录: I' G6 W% I6 z( Q: j" {3 @5 j. ?  O
7 B" o; X( w- w+ Y: t) e. G
HRESULT getOneRecord( _RecordsetPtr ptrRs,
$ i0 p4 m. G: g! O+ e: ]                      const long lNoOfColumns,* q4 j( t& a" I; a1 `6 h1 N! u0 N
                      _variant_t varValue[] ); u; g$ Y4 M4 {
{0 ^+ d& `% f4 X  x8 m
    try
; F7 w, n3 @* g, F* ^: x3 F- }    {# V& K+ i4 V! {) P+ k- q
        // 参数变量
3 Z9 }/ v  x1 Y+ U2 P( @1 `        _variant_t l_vaIndex;. E( t, I# h# G% h9 J* }2 e
        l_vaIndex.vt = VT_I2;
0 {7 L, x- |; ?* l/ g* @  E2 c/ S! @! s
        // 循环取得列的值& R7 c5 |$ _# O. ]/ d
        for( long lIndex = 0; lIndex < lNoOfColumns; lIndex++ )
) T; J! B" }  u2 n        { ' x0 G: H& t9 \) g- G5 D
            l_vaIndex.iVal = lIndex;
4 K( N2 A4 E0 B" e/ @
9 a( ^" v& R4 @3 e1 `            // 取得字段值
; ]7 K, m! [. J/ ]' @: `            varValue[lIndex] = ptrRs->Fields->GetItem(l_vaIndex)->Value;! ]" w, ]& e( p4 F6 U9 |
        }
' T% k, l5 g! x0 w9 W        return S_OK;' a& Q/ s# e0 {  x# B. h6 {1 T0 W
    }$ ^$ ^# s9 P, d+ }
    catch( _com_error & a_pComError )
4 X6 N# P4 t2 B- e* W+ M2 x  ^    {# ^# Y+ ?* U' E0 v* j# ^( _+ i
        …. // 错误处理
- {" A" Z/ l, z# C6 a+ ^% w        return E_UNEXPECTED;; d* C6 ~. k7 H2 d: W  I
    }
3 ^4 e0 W  l8 J    catch(...)# z* v8 Z" |  r  o) }. _% J* f
    {
8 `( ]" A# P$ V4 r        …. // 错误处理3 `4 G' ^1 f% s# c
        return E_UNEXPECTED;5 _) b- M+ O! V% d( m
    }, p) W0 E- G9 ?: a+ s+ Q
}: Q* Z  _2 y1 W6 e
# t$ j  B3 H2 x* D3 h+ C9 s
) M. f& X  h. a/ h
7.出错情况下错误信息的取得6 v% X) m6 V# G- M6 W

9 ~* o' }4 g/ i% s- S% c. qvoid ErrorFunc( _com_error &pComError, _ConnectionPtr ptrConn );
  c1 u2 I2 [, ]7 P& c7 C{9 }: q5 o" y+ F( E1 F. e7 A
    // COM 错误取得0 c; m6 D% U. O% t4 r& o3 F  G% J. e
    // 当执行COM功能的时候,如果出错,可以捕捉到_com_error的异常
$ N2 U! H4 v7 Y& [( l7 ?, R    char lpComErrorStr512];
6 X$ f$ E- m' `& i3 f$ V7 A: k  z
    sprintf( lpComErrorStr512,3 V2 p" \' c& y1 P4 w" \4 V5 g# i
             "ErrorCode = %08lx \ Error Message = %s \ Source = %s \ Description = %s ",/ I" K0 q  x0 m* }9 t, C
             pComError.Error(),                  // 错误编号
' E- X/ P- J6 {2 U+ N* g4 F9 W             pComError.ErrorMessage(),           // 错误信息- Z) X( o# p( I! _8 T% ?
             (LPCSTR) pComError.Source(),        // 错误源2 D( _7 o" s  |8 l  S7 O; n
             (LPCSTR) pComError.Description() ); // 错误描述
9 ~7 R! A( K+ j8 O
  D3 _+ A9 i* K. U9 R1 r7 J2 g    // 通过上面的代码我们可以看出,_com_error对象中可以得到COM所有出错的信息5 A$ H8 o. d! T+ i) y
    // ADO错误取得6 ^$ x4 J- s1 _# f) [
" e  A( J4 [: k# V5 X8 R
    ErrorPtr pErr = NULL;
/ l+ ]# I: |3 f3 o    if( (ptrConn ->Errors->Count) > 0)
- x9 _8 o: ^1 x' f( {0 i    {* T6 c8 X% q" P/ t
        long nCount = ptrConn ->Errors->Count;4 t8 \4 V" T4 z) k/ i+ x1 e
        for( long i = 0; i < nCount; i++ )
6 N# W  ]+ L. d6 d- W! b        {$ y. n3 }: }9 P/ X( D# n* X) U
            pErr = a_pConnPtr->Errors->GetItem(i);8 t, {. ^0 e- U" ?7 X" J9 w
6 H# y$ z- j4 D- k  B/ k! ?* w3 ~
            char l_pchErrorString[512];5 [+ `) u. L* |6 t+ V  |  U& x7 e3 q2 c
            sprintf( l_pchErrorString,"Error:\n Error number: %x\t%s",; M5 H$ M' m) ~6 F# D+ `  ]
                     pErr->Number,         // 错误编号2 P% U  h  g8 l* l5 K2 M0 G
                     pErr->Description );  // 错误描述" M+ U* y1 g5 W+ @2 {
        }2 u- ~% g, X( W# N2 a  @
    }
& z$ W. t& t  l2 U; Q9 Y" D
5 n! G# a( m3 x. ~- K! v8 K    // ADO 处理出错的情况下, 在connection对象里面都有记录,可以通过访问
$ p  F1 N! S! n3 O* G& I, g    // connection 对象取得错误编号和错误信息。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-13 08:24 , Processed in 0.018525 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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