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

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

[复制链接]
发表于 2004-1-31 18:14:29 | 显示全部楼层 |阅读模式
  对于在WINDOWS上编写数据库程序的程序员来说,ActiveX Data Objects (ADO) 是最常使用的技术了,通过ADO可以简单的实现数据库的连接以及数据访问。但是在VC++中使用ADO时,却因为是使用COM的方式来调用,常常出现一些系统无法编译通过,或使用中程序非法出错的问题,在这里想大概介绍一下VC++中调用ADO的常用方法。* {: O/ o5 ?1 J
( E4 L. Y5 F7 c% T6 P
1、 用import导入ADO 的 COM 文件msado15.dll1 t' W( o7 n/ N' Z

+ B: Z+ v; j! P* D  l例如:! n- v* I) A3 T

5 Q8 z- U1 `% c, E" e1 s' U6 w; U  #import "C:\Program Files\Common Files\System\ADO\msado15.dll"\
" B8 B: x6 L, ~: P) E+ R! g9 {; `0 j
   no_namespace
$ F$ ?$ n" ~, Y( ~6 T- g1 p
( M) p0 g0 X' l* B7 q5 ]2 S9 O0 _8 d' Z' n
  Z$ E; w! F8 o+ b5 P2、COM 使用时初始化. \3 E8 S; U( A: _

" _" l# v% f/ P5 y( e/ T0 uHRESULT ComInit()8 X: f8 c& Z5 I# G
{
# I# t% n5 G0 q+ {* N1 i    HRESULT hr = S_OK;             // 默认返回值7 I$ s6 D6 B' K( D( m- L" m" t% s
    if FAILED(CoInitialize(NULL))  // COM 初始化调用" g; H3 \* G) w7 ]6 {3 q
    {
, R. _$ n6 M* b; h        CoUninitialize();4 G' Q  A+ X8 S: E
        hr = E_UNEXPECTED;; n' d( b- k$ @
    }* I, L' G0 C) r; f/ D0 O% J+ _
    return hr;" K) }* @# d, \8 A
}
  u  V0 S( L8 B1 }  Z
5 A6 j4 m8 C  L! j: G$ S
; n0 }* C, K; s  @% @3、建立数据库连接
1 j' F8 q7 U6 x  x. u+ J1 Q5 `- G/ ~& I$ v4 S
HRESULT ConnectToDB( LPSTR pUserId ,                    // 用户名
- H3 I! ?/ t) D: l! d1 G& e! k0 k                     LPSTR pConnString,                 // 连接字串
4 c$ J5 _5 a1 v! p* [2 o                     LPSTR pUserPassword ,              // 用户密码
/ m) I  d# M: F! {, _                     ConnectOptionEnum ConnectOption )  // 连接参数
/ K/ U( g7 R6 b/ ^- ~3 d{: K* _7 V9 L0 V- _1 P8 h

; \) t* O# w  e; y    HRESULT hr = S_OK;        // 默认返回值
( L. Q+ n4 Y2 i2 b# o    _ConnectionPtr ptrConn;   // 定义Connection对象
) e9 K! I+ Z1 [2 S
2 G; t: \0 R: g* H2 ?) N    try
" ?9 x2 E# w2 b4 v, a( {    {
# m1 ~  B/ b, w$ k, A        // 创建一个连接实体
! {" T9 g; s  {        hr = ptrConn.CreateInstance( __uuidof(Connection) );
) G+ Z3 `6 R- X, ]  ^; l3 [% [9 p: S3 m* X' e: w
        // 设定连接等待的最大秒数,默认是15秒
0 x: h" L  i% f, ]        ptrConn->ConnectionTimeout = 20! A; i; x/ m7 q2 `+ y8 _; l* e7 E

* g* Q3 N4 I/ x' q        // 打开连接; y) D; x5 o/ H8 }
        hr = ptrConn->Open( pConnString, pUserId, pUserPassword, ConnectOption );' e7 @1 A6 Q% p9 V
        return hr;
6 p) Q& r' a/ ]    }
3 P" F! w% N3 j) Z    catch( _com_error & pComError )
4 B! P5 }9 C% _    {* d$ Z- W: I3 d9 t% Z5 L5 F
        …… // 错误处理
/ ]) [- ~0 y; l4 v4 H" R2 E# z        return E_UNEXPECTED;
  q9 Q+ t* Y# `, o2 H: B. x) R    }
6 w- Q& D$ e3 x( m6 q$ [}
, q& ]# I( b5 ?; ~
- E: C/ C$ S# D2 W5 b1 Y
& I& [- W5 J  n, o, p+ N4.执行一个SQL 查询,得到数据集(recordset)8 y  G+ B" [' ?4 N7 s8 M! j2 F5 Y
- }2 t: e* [5 y  u4 U. `( z
_RecordsetPtr GetRecordSet( LPSTR strSql, _ConnectionPtr ptrConn )5 [! |0 C( S. q2 Q; j! ?9 T
{0 I4 ]1 V, Q" `& c* v  d1 N
    try" _1 z) ?  R$ Y% ]
    {
; M0 m- }: ^+ m. b        RecordsetPtr ptrRS; // recordset 对象
7 S! M3 ?; r7 c5 K
7 U! l6 o" j+ _7 j- O6 T* h+ G        // 创建recordset 对象实体
$ l% a- b5 p. w' [        ptrRS.CreateInstance( __uuidof(Recordset) );) K" l/ K. r) j9 b
        ptrRS->Open( strSql, ptrConn.GetInterfacePtr(), adOpenForwardOnly, 9 g6 O% H6 Q( I# i3 j
adLockUnspecified, adCmdText );
( L+ z; r  N( w. ~7 n$ j" F& s) G0 s  \- K, a0 i& c' l- W8 l
        或者
: d. l# N3 G6 N. J4 t) b        ptrRS = ptrConn ->Execute( m_ strSql,NULL, adCmdText );: ^1 F8 `& V, i& d& C6 o% ?
        return ptrRS;' Z# c( Z) [5 ^$ n$ ?9 {
    }* I" Q  z+ q# y6 N) q* P7 A
    catch( _com_error & a_pComError )
9 a. P% C7 k/ v0 `7 C' |    {
2 X6 o( y' L% B8 x! |        ….// 错误处理) x  R; R- Y0 C
        return NULL;
  V8 G9 G0 [! o9 G3 @    }1 \: v  U) u9 M+ G, _; u
}
- \7 A1 }; \/ L3 s& [
% Q# f1 U- D2 C7 i, P, w
) V2 o. v& P4 s6 U3 w9 ^5.通过数据集(recordset)得到列的名称5 W( w) y0 k* q" t. M# _
+ T$ Y" d/ H! j3 U
HRESULT GetColumnNames( _RecordsetPtr ptrRs,        // recordset 对象' ?! y) @  j: h0 E7 \" V6 v% X
                        char strColNames[][255],
0 z' }+ V6 B* X$ s  w                        DataTypeEnum iColTypes[] )
9 i4 X. z' `) e& Q{: _: d) j* n1 z+ J% ^
    try8 z  [; [( }2 w
    { // 参数变量, }8 U& C7 v2 H8 M% k# E
        _variant_t l_vaIndex;2 `; M. Z; D( }4 ^- Y

& {3 G/ L6 e- L: o- m$ d3 u: o" N        l_vaIndex.vt = VT_I2;) F+ y$ ?. Z9 g  `6 I2 [

* g6 |8 k1 Z+ G3 M        // COLUMNS总数
$ Y  B4 u5 N4 Q6 d  D        long lColCount;
3 g4 M+ D9 v0 p6 b) h6 S8 a
8 S- k' R3 h  y* n! F7 Y' ?8 l0 ~9 r        lColCount = ptrRs ->Fields->Count;
$ ^0 t  t' g) d
0 @4 L1 H+ G! _+ g. }: t        // 循环取得列的属性和名称
0 W" F* E- f9 C# p; o) r        for( int iIndex = 0 ; iIndex < lColCount; iIndex++ )
; `. r0 d5 E/ l8 a        {
! E! X7 y7 X. X            l_vaIndex.iVal = iIndex; // 设置循环索引, _3 \. V) e/ D, z, o

9 Q+ S" `0 I8 t2 M$ |& N8 R' V            // 取得字段名称, _! K" K! V* X' m, I& b, K
            sprintf(strColNames[iIndex], "%s", (LPSTR)ptrRs ->Fields->GetItem(l_vaIndex)->Name);
- X6 ?; ?( N' i; k2 W& s6 w! B* B& \! a- T( ~0 }( N
            // 取得字段属性
  Q( s6 E% j, j3 v  Q- H            iColTypes = ptrRs ->Fields->GetItem(l_vaIndex)->Type;$ V' x7 Z; a* R0 Y% R) }4 I2 }
        }! O; u5 j9 I+ F9 z6 i
        return S_OK;
7 U2 \: v! l0 z8 W4 U( g! J+ Q    }
  J$ L: W6 a" l# N0 ~* q# F% {$ J    catch( _com_error & a_pComError )+ O* H3 U" J0 }( Z" k$ `1 y. g: g
    {
: |% i- B% S- p) |4 P+ {        …. // 错误处理% i% a  P9 R2 k3 t* k" J
        return E_UNEXPECTED;8 k  `1 i3 o# q0 [0 {) ?- E
    }& ], H+ ?! g! s, |8 s/ Y) p4 H
    catch(...)1 F$ Q" M; G: k
    {" w) G8 q: D+ h, `$ Q
        …. // 错误处理
: ]3 Q$ U6 ]8 J, }+ N$ `9 m        return E_UNEXPECTED;7 V) S' U0 O. I: p) T. s8 F
    }
: D* P, E) k! y  S' u+ {) H}
" Z# V  U$ ?4 b! K6 }5 O, N( m, D1 X. q4 d

, r) D9 y+ Y$ E& R% E% c$ F6.通过数据集(recordset)得到当前行记录
, {, s6 R2 d. O. x5 ^  c- W6 y0 f6 i# T, U% W' D9 ]" V( {! i
HRESULT getOneRecord( _RecordsetPtr ptrRs,' e1 Q% X  k' N0 D5 W
                      const long lNoOfColumns,$ i6 N6 _: t6 w7 \
                      _variant_t varValue[] )
1 @' U8 M" c5 i3 f1 W7 V. m{
( \$ C" f3 N! }7 U+ y    try5 `) \. t. I/ @# g* r: t2 H
    {
9 u1 f5 C7 M" C4 Z, G. k# D        // 参数变量
0 s7 A) C  e/ I1 P; c/ I        _variant_t l_vaIndex;
) d0 }+ C" s& P; n7 V& d" g6 ?, n        l_vaIndex.vt = VT_I2;- m9 m" Q% B% l* p3 R6 d

$ X: k, G' T1 u! l* H        // 循环取得列的值
( R7 c4 d( i6 k) w. @% z- L* }) k        for( long lIndex = 0; lIndex < lNoOfColumns; lIndex++ )
( P) _7 K- D% b6 b        { $ \9 K# f# Q- V( u# M% U
            l_vaIndex.iVal = lIndex;
5 v9 a9 G* ?) V. s/ O& {3 K5 g
3 z* W4 ?5 B' Z            // 取得字段值
. l# [; d# ~3 N$ W* a( d            varValue[lIndex] = ptrRs->Fields->GetItem(l_vaIndex)->Value;
% o# n- D4 m# o, k        }; o; K9 q! e5 ^5 E( v
        return S_OK;. N+ ]: K! o: F& K7 a4 L( T2 v
    }
$ W1 O* T: S, a7 X1 B% v    catch( _com_error & a_pComError )6 C4 p( }' A3 x8 X4 |
    {; A( E. G% l+ U: z8 d+ ^; c
        …. // 错误处理# J8 r) X) c6 Q1 Z
        return E_UNEXPECTED;+ a& `6 i& W) l) V- ~
    }7 E$ \3 ]2 u9 N7 w
    catch(...)
1 M6 x! Y+ @+ y/ C, p+ w4 G    {
+ v* s, K/ B5 E        …. // 错误处理
: l- d& I& G# L        return E_UNEXPECTED;6 n9 u8 u# y4 K7 a6 L4 ?1 G0 W9 C
    }* p2 \$ t" Y; y% O
}9 p6 s9 M/ a, b$ U/ `3 [0 a- L! F# {) w8 k

' C1 C8 [0 m6 W+ l
; B2 V. l* I$ |7.出错情况下错误信息的取得* U$ l9 |3 T( k9 ~0 h

# y2 g% k) T$ E$ \7 J* j0 Wvoid ErrorFunc( _com_error &pComError, _ConnectionPtr ptrConn );
3 M: C8 X: V' v. _& p4 U{
. [$ X  x$ T& D& c4 J    // COM 错误取得4 t; @6 _- `2 E  l% {
    // 当执行COM功能的时候,如果出错,可以捕捉到_com_error的异常
" n% r0 L  F9 i; C& d; Y    char lpComErrorStr512];$ ^6 J2 b7 v2 _4 U( r+ I7 r! ~
4 e4 q0 c  A8 [% q( x3 [
    sprintf( lpComErrorStr512,
7 R- @& K$ k# G             "ErrorCode = %08lx \ Error Message = %s \ Source = %s \ Description = %s ",  w7 R% n; ]- J! H
             pComError.Error(),                  // 错误编号
& Y( v# _; e6 m0 U" G             pComError.ErrorMessage(),           // 错误信息
5 n% n* D! k. D6 z             (LPCSTR) pComError.Source(),        // 错误源- J5 l2 E2 D" }. p$ W' A- e
             (LPCSTR) pComError.Description() ); // 错误描述
! ^5 x+ l+ c( O( D% `, K  c- N$ q
    // 通过上面的代码我们可以看出,_com_error对象中可以得到COM所有出错的信息
# W- C$ c) U0 D2 G4 r6 f9 A- m    // ADO错误取得
" v' D6 b; _+ @  l) u* e/ O
  K8 {  Z/ q& l: E    ErrorPtr pErr = NULL;7 V2 r% @" w' z# X7 ~# I
    if( (ptrConn ->Errors->Count) > 0)# A# x8 u4 n" T0 \! G8 R6 V3 l
    {
1 w! F+ ~; T6 o6 l% s        long nCount = ptrConn ->Errors->Count;/ ?2 E4 Q( K, L3 [* Z
        for( long i = 0; i < nCount; i++ )0 m2 g; G0 Z8 \
        {; t' q0 K/ q6 f0 g# e0 A
            pErr = a_pConnPtr->Errors->GetItem(i);
4 D% {8 [: m& `( c5 v8 M5 Z! Z8 D$ `
            char l_pchErrorString[512];
7 G! s) {4 n6 R  `+ q            sprintf( l_pchErrorString,"Error:\n Error number: %x\t%s",2 L: n7 J  ]: P
                     pErr->Number,         // 错误编号& v; p% Z5 I) X* C1 K! z
                     pErr->Description );  // 错误描述
  F/ P1 V% ^# }' s        }
$ x3 X& b$ q1 [3 x9 J    }
" r5 J9 z* j/ W, d5 M* @+ n; i+ [6 [) W; X* H4 A/ Y- D4 r
    // ADO 处理出错的情况下, 在connection对象里面都有记录,可以通过访问8 u# B2 z1 W1 |" j" Q$ K
    // connection 对象取得错误编号和错误信息。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-13 21:32 , Processed in 0.016842 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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