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

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

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

0 @( {. H& V" L1、 用import导入ADO 的 COM 文件msado15.dll
1 R" D- n" w( i# A3 P, @& t& X9 e' F1 S$ v$ G) v. W& o; B' d
例如:
% h! X( i# w; o  k" R7 ^* f: E7 d4 F0 V! \
  #import "C:\Program Files\Common Files\System\ADO\msado15.dll"\; ~. I9 K) V( k

4 c( s% q# t' C( K. l# D   no_namespace
% g! u7 |* F4 A4 \5 z. W: H# z6 l/ h  v
- @2 D$ V# V5 C1 D7 }2 H
2、COM 使用时初始化# y  P+ Y! M" Q7 T6 g- @2 ]$ L
- M2 ?' S$ c% u) B; m8 S! n( G, @
HRESULT ComInit()- W) K) F* Z9 f) T' i& S
{
+ w, i5 J& w$ W# o2 @  T$ Y    HRESULT hr = S_OK;             // 默认返回值
/ W1 B, s1 j1 L/ l4 P    if FAILED(CoInitialize(NULL))  // COM 初始化调用) L2 X6 o8 R- \1 K- K+ C
    {
3 [, H8 M2 h, ~" U        CoUninitialize();/ q# l+ w, m( d
        hr = E_UNEXPECTED;
7 n+ V& P( @# @" G* A6 `2 N+ [    }
2 m: E* Z' C6 I+ q    return hr;; _/ @0 Q+ W$ T3 h# f5 g
}$ z. m8 _. E7 \! O7 Y! W* Z
2 Z4 |: ]1 }3 H: v+ H

& L% r; Z' u8 Y* b& l3 M3、建立数据库连接
9 n( ]9 b) t9 W- U0 u+ p# d7 }2 v5 Z( H7 v; U( q
HRESULT ConnectToDB( LPSTR pUserId ,                    // 用户名( a- `$ C8 }5 Y& i) r* z5 E: X
                     LPSTR pConnString,                 // 连接字串 % i3 C  b! _! O
                     LPSTR pUserPassword ,              // 用户密码
+ {/ v( f4 u- a                     ConnectOptionEnum ConnectOption )  // 连接参数; g* a& f8 }' C( m" Y' u; d* W
{1 ~3 M+ o; P* }0 f8 X% N7 Q3 D
. E0 f# r" ?& R
    HRESULT hr = S_OK;        // 默认返回值# P9 {3 W  d4 K& _
    _ConnectionPtr ptrConn;   // 定义Connection对象
6 N% \$ g0 N9 r+ k$ }
2 Z+ z  o% G/ W. F2 Y/ {; c9 u    try/ k5 n& P- E% ~
    {* Y$ ~2 I( j/ G2 ?" h
        // 创建一个连接实体
; |$ l* s: O- |! m5 z/ I        hr = ptrConn.CreateInstance( __uuidof(Connection) );
' Z9 t: n8 o+ E$ R; B3 c* d; Y, \$ N: T
        // 设定连接等待的最大秒数,默认是15秒4 Y- Y9 [( i7 {- A. C! H+ c6 F1 @! e
        ptrConn->ConnectionTimeout = 20
7 L3 n5 Y9 ~( A; }2 [
+ f$ g! P' Y2 p% q8 q, @  r        // 打开连接/ X+ ^% U- O: O4 \9 a3 z/ I
        hr = ptrConn->Open( pConnString, pUserId, pUserPassword, ConnectOption );
! y# r8 e( i" b* T5 `4 U$ z, Z        return hr;, s7 O3 G; h. g
    }
5 H% u0 I/ W$ |* H. }* g6 x    catch( _com_error & pComError )
" N0 J$ K  X, |! h    {
. \0 [9 N: o6 r( |0 q        …… // 错误处理
( E) U) [- p. [" }, p' P$ I        return E_UNEXPECTED;
. |( I. o- Q5 U. D% H$ [, I7 Z    }
! K# [1 R! g* U, e! W& S}
5 d3 r" N7 p  ]5 @6 B
) W+ b; i4 Z, d/ [. f4 j- f
- U: x, O3 G$ x4.执行一个SQL 查询,得到数据集(recordset)2 H) s0 @  w( W( M  b7 R1 ?# {

+ |2 }8 r5 W2 l4 o) x( ]# M! v7 a+ a_RecordsetPtr GetRecordSet( LPSTR strSql, _ConnectionPtr ptrConn )1 x$ d  l- ?* N( h
{  K) J. h. t; Q) \( R
    try
) Q) V8 Y' t7 l# L1 Q& X    {
# m8 b9 |4 k- D        RecordsetPtr ptrRS; // recordset 对象% l0 K$ M7 |2 |- E3 o

. W) `9 a8 k3 `        // 创建recordset 对象实体
5 a& Z) s) {, E# x3 m        ptrRS.CreateInstance( __uuidof(Recordset) );
( b/ a# A" B' m6 y9 n! y        ptrRS->Open( strSql, ptrConn.GetInterfacePtr(), adOpenForwardOnly,
  J5 S* Y) ^$ L# H0 r  C" jadLockUnspecified, adCmdText );
* h+ s' J; S" b! A9 C& ?
7 J! Y4 o- k0 J$ b' x4 c        或者+ a- h  q( @+ \
        ptrRS = ptrConn ->Execute( m_ strSql,NULL, adCmdText );
" j/ V$ C; z2 U2 b        return ptrRS;7 {- b! X5 m) P% m% k6 R$ K: `
    }) |' z; o8 h( c/ w: h; i1 k) T
    catch( _com_error & a_pComError )
  ]- j, e5 P" O8 f+ ^- D3 `! i    {
/ C7 A" j) T) P, e) i6 f        ….// 错误处理) O2 S/ k/ _5 u0 W
        return NULL;7 v- f) B- ]. a$ R3 j/ d* I) E
    }" T" O# [0 \3 U# r% _5 X$ t
}
7 |5 k( w9 y8 r' `- y0 V& u- Z' |  g, H4 m' N0 F

: x; p! p- ]# }% A. [5.通过数据集(recordset)得到列的名称
: Q  v1 q/ J3 E4 R9 l/ `2 U- X/ _6 C  i" H
HRESULT GetColumnNames( _RecordsetPtr ptrRs,        // recordset 对象
0 ^$ ]5 D$ W3 q6 [& v6 x, F! t                        char strColNames[][255],
% X6 V2 b* n8 f, f$ @3 {: d# h                        DataTypeEnum iColTypes[] )
  F4 p$ k8 k3 k) x{7 e2 d  i- ^( ^# M# V
    try
1 o( ^. C6 v1 F' l    { // 参数变量
9 d$ }7 M, T, i8 z7 _        _variant_t l_vaIndex;
- Z% r2 D: U+ Z4 b( Z
: Z8 u  K5 b$ I        l_vaIndex.vt = VT_I2;, k. [( K# w  e; n. B6 K

& c" a0 f! z* y3 B3 R        // COLUMNS总数
' p% X( P+ Q5 }. v4 [2 n, ~        long lColCount;
2 K6 u& Y6 S, m
/ J/ [4 V6 i8 {/ u( T$ P. ?: I        lColCount = ptrRs ->Fields->Count;  c- a+ f; l& i' W7 Z. ?

- h; A! a8 \. i7 y        // 循环取得列的属性和名称; F; i, i: k$ ?6 u3 O4 x
        for( int iIndex = 0 ; iIndex < lColCount; iIndex++ )
3 x  F: X6 e% G3 L        {
# |3 h  l) J# S+ B: a            l_vaIndex.iVal = iIndex; // 设置循环索引
1 m2 k1 D: v; A6 U, C$ U) D
: @8 q3 O% ?+ H3 }1 Y0 l, B" P            // 取得字段名称$ V/ b' N1 e# a; O
            sprintf(strColNames[iIndex], "%s", (LPSTR)ptrRs ->Fields->GetItem(l_vaIndex)->Name);& H8 F# ~( S7 P# e$ \- ?5 c

4 d/ M- G  H2 t6 R$ Z7 ~+ h! V            // 取得字段属性' X$ m+ y! O& U3 m7 G
            iColTypes = ptrRs ->Fields->GetItem(l_vaIndex)->Type;
* z) _/ o- {& {- G        }
9 K2 |/ E2 Z1 v3 b' g# P        return S_OK;  P  Q4 j( N8 h! t3 D( n' P
    }1 D9 J4 A# x7 c& z
    catch( _com_error & a_pComError )
+ k  q5 _* Q& V  F4 ^7 W3 c6 z    {
+ l: O' D6 c! a9 d6 e( |0 `        …. // 错误处理* x5 b5 v) }# k7 I
        return E_UNEXPECTED;: }3 d5 q/ r2 h' _, s3 h
    }" N+ C9 N7 r1 y! R7 d
    catch(...)
0 _6 ~3 ?0 C6 E& b4 M    {
' j: A# A* h2 Y        …. // 错误处理6 w( P% ]9 D4 q9 r" K' X" q
        return E_UNEXPECTED;2 m7 v. S5 r7 T# R- J  k
    }" J' x1 j8 v3 t- m
}
8 b9 y0 j0 b1 p$ B/ W9 H( }8 Q5 O  M8 u3 p. ~* u

9 ^) t3 i+ R* n, N5 ]+ n2 f6.通过数据集(recordset)得到当前行记录( m' B" ?$ i- Y9 a% x

1 t% n2 U) O' D: L3 ?HRESULT getOneRecord( _RecordsetPtr ptrRs,) _4 I/ M6 Z. x8 M! q  m1 D
                      const long lNoOfColumns,% O. Z5 P% t  y* z
                      _variant_t varValue[] )
  v6 V. c; V6 O{
& t% {$ ~1 ]; g* y" X1 X' H    try. a, ^/ o' g# m. ~( c8 Q6 v
    {& X; M9 i( T# ?' L6 P
        // 参数变量' q6 t' n3 D+ J2 [
        _variant_t l_vaIndex;
8 [9 h8 A* e7 Z& C$ y9 P        l_vaIndex.vt = VT_I2;) U+ o, _! j+ d* g9 m% g! W
, T# m1 p4 N/ t; Y
        // 循环取得列的值
9 D. l" T( U; [) ?9 r6 H7 e3 u        for( long lIndex = 0; lIndex < lNoOfColumns; lIndex++ )
* @: q4 O- }; v) f        { ' E: q/ I- T4 J  ?3 [- r
            l_vaIndex.iVal = lIndex;# [3 Z5 r. M) y. n9 h

( W/ Y+ t. M( N2 u* L2 g            // 取得字段值& v% J$ q# N$ w8 p( k0 W2 N4 y4 f, e
            varValue[lIndex] = ptrRs->Fields->GetItem(l_vaIndex)->Value;
4 R6 F, A  [- b        }
0 K' a6 E. _; l' ]5 h8 K        return S_OK;
7 P. Z8 R4 g5 r% P6 I$ _6 G& l    }$ p( v6 ?" f$ o4 k
    catch( _com_error & a_pComError )
5 Z! m' G. W! [    {$ B& ]* z% N, Y7 k: T  W
        …. // 错误处理
& H- x: c8 G& D: P; A% c4 D% j        return E_UNEXPECTED;# |& G4 m) S) v& j; ~" H
    }) W+ j1 \; _- b6 m; P
    catch(...): ~2 B$ M. o8 J
    {1 c) Y- r' E* d) a0 g# q0 v
        …. // 错误处理$ s6 @. f9 O2 i' X4 w# ?6 y
        return E_UNEXPECTED;
7 V9 R' |8 J+ n& V: z) |: _    }3 l' T' `1 W8 z, o  g
}
, @  K! A/ ~% P7 z$ ~/ B1 R/ P9 s2 `$ a5 b: z; O

  Y, e! V/ ]4 k& z( k7.出错情况下错误信息的取得
$ v5 z3 M! L, o/ n% `9 e
! v' F  o+ Y. q; pvoid ErrorFunc( _com_error &pComError, _ConnectionPtr ptrConn );4 K- x5 o6 F% b* \1 X
{7 b# k: o# F; l6 {2 K$ M
    // COM 错误取得
! I/ F  L% [3 @- V    // 当执行COM功能的时候,如果出错,可以捕捉到_com_error的异常- i  x4 ]8 p9 C6 T6 ]
    char lpComErrorStr512];
: W3 T6 }2 U2 C9 k2 D5 [; l( t& u  F6 l# q5 f
    sprintf( lpComErrorStr512,
/ x9 t  u0 r$ E- T' a& n             "ErrorCode = %08lx \ Error Message = %s \ Source = %s \ Description = %s ",) G2 g2 n8 X, M% M) T) X! j/ Q0 \
             pComError.Error(),                  // 错误编号
: `; m2 E* x0 _% Y& t- l% q             pComError.ErrorMessage(),           // 错误信息! ]9 ~; \* b/ ^3 w
             (LPCSTR) pComError.Source(),        // 错误源
! E3 Z$ Y6 z* Y' D             (LPCSTR) pComError.Description() ); // 错误描述" n! ^8 ^. d9 I

' y  C2 v9 A! n: p    // 通过上面的代码我们可以看出,_com_error对象中可以得到COM所有出错的信息
( ?  M* Z8 _; @0 T( S    // ADO错误取得+ U$ d  ~) U2 e3 o% r3 h9 p
1 _. g2 b, A, D# p- E+ g* [
    ErrorPtr pErr = NULL;5 U  B0 F6 N6 f
    if( (ptrConn ->Errors->Count) > 0)
4 |  E( |8 _1 D6 r  W    {
8 g1 {: Z7 u1 U3 u! u4 g        long nCount = ptrConn ->Errors->Count;
; h) [3 m1 g1 M        for( long i = 0; i < nCount; i++ )
( o# X9 U1 n  N& p5 N" _( M        {
# C% a+ x. t' C, ^& `) M- m  u            pErr = a_pConnPtr->Errors->GetItem(i);
( r8 K- U) w" I! {
4 @$ R0 ]$ q& D: d            char l_pchErrorString[512];
, e' n8 a4 \: v9 a+ j9 }) G+ w            sprintf( l_pchErrorString,"Error:\n Error number: %x\t%s",8 @5 y% r8 ^* G% C' m: r
                     pErr->Number,         // 错误编号
& p! q. Z$ X: R                     pErr->Description );  // 错误描述
1 p) Y; n- f% }9 q        }- f0 R' c: k- U* m2 M$ S3 [
    }
, j  }6 i. {' h( ^) G- ~) Q
! Q$ P$ D+ g; e" ?# z: G' f    // ADO 处理出错的情况下, 在connection对象里面都有记录,可以通过访问3 v$ e* n3 ^" f  {9 x
    // connection 对象取得错误编号和错误信息。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 10:22 , Processed in 0.018519 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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