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

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

[复制链接]
发表于 2004-1-31 18:14:29 | 显示全部楼层 |阅读模式
  对于在WINDOWS上编写数据库程序的程序员来说,ActiveX Data Objects (ADO) 是最常使用的技术了,通过ADO可以简单的实现数据库的连接以及数据访问。但是在VC++中使用ADO时,却因为是使用COM的方式来调用,常常出现一些系统无法编译通过,或使用中程序非法出错的问题,在这里想大概介绍一下VC++中调用ADO的常用方法。
  S: \7 c; a& F7 q  s& k) t- v( u6 c  t1 V
1、 用import导入ADO 的 COM 文件msado15.dll) i2 x8 b/ s; F" X5 c$ u
3 r% s0 d/ q% S  \: U
例如:/ N4 r0 [* {# D" N+ T- u

9 p* S( M& ~. [$ L0 m, y# C9 S  #import "C:\Program Files\Common Files\System\ADO\msado15.dll"\
1 k# y1 \/ t( Q5 D
3 G! P1 h, ?$ ]- T, K   no_namespace
0 [, Q% C, R( r- ?* r( f9 C2 u/ A, N2 G" |  N
- {" {: ?( V5 p+ @! |
2、COM 使用时初始化
" L6 k- W" V' Z, t$ P7 ~: Y* H: C7 J
HRESULT ComInit()8 N' U/ q% a( ]( |; b; a- i
{ 4 A8 g' k6 q+ Q1 B2 r" U8 }
    HRESULT hr = S_OK;             // 默认返回值4 S3 c, y' Z9 w% Z& y7 R
    if FAILED(CoInitialize(NULL))  // COM 初始化调用
' E; r4 {* S8 h4 h0 D4 R7 J    {/ Q( ~+ A2 B7 g
        CoUninitialize();$ P' }* |5 U3 Z; r1 p2 [
        hr = E_UNEXPECTED;2 z) p/ y9 e; ^# ^  m4 ]
    }$ S$ r1 M( u3 c+ v2 J
    return hr;1 u+ p# T' f# f; @* F1 l
}9 t" f9 a1 \% e+ L$ m$ h6 ~

. b3 n$ S; w4 `7 b7 Z" G- N9 f- m# v: ~
3、建立数据库连接
; h: s7 J. h' T! }& Y  H
1 Q; g( d2 P; ~! @# RHRESULT ConnectToDB( LPSTR pUserId ,                    // 用户名
# Y+ O8 u& t, s3 d                     LPSTR pConnString,                 // 连接字串
$ y  q: V6 F( r2 j5 C) r: t2 {                     LPSTR pUserPassword ,              // 用户密码
0 K4 i6 P3 }2 y: k5 \                     ConnectOptionEnum ConnectOption )  // 连接参数
- ^' }1 V9 R$ Z  M: ?{
3 p1 m1 \6 Z. s7 @8 C0 E7 w  M8 N6 w' C. X2 `( a
    HRESULT hr = S_OK;        // 默认返回值: ~) c5 N" I$ R' @
    _ConnectionPtr ptrConn;   // 定义Connection对象
# @& k% ^0 h, Y' T5 b  V5 q4 C) _8 A, u6 K
    try
  B3 B# K- N3 X' g9 R. [    {
/ s( E0 d  a0 u$ [        // 创建一个连接实体! N) _5 D% N; L7 F$ z+ U8 E
        hr = ptrConn.CreateInstance( __uuidof(Connection) );
( ?3 x/ f# C5 y  q# f# M7 i9 a- f. A& R# ~" W3 _& U
        // 设定连接等待的最大秒数,默认是15秒
% A# X$ s9 M" e5 S' C5 M1 r        ptrConn->ConnectionTimeout = 20) @; U3 d' I& T# p) K2 I/ z

3 ], L8 K5 F: b  Y4 z        // 打开连接! v: x( q1 U6 U* D  N( I
        hr = ptrConn->Open( pConnString, pUserId, pUserPassword, ConnectOption );" T- _2 b% a7 i- b
        return hr;
0 _8 J/ j" Z3 z) ~) O* D    }
7 k" N" ^- T7 R% I' S. w    catch( _com_error & pComError )' S4 @: [0 @  r5 |9 s
    {
0 ^/ b# M/ q" p- p% q+ K2 X- U( A        …… // 错误处理
6 i. d# @, A' Q: S. R0 {        return E_UNEXPECTED;
( _- v; c+ j) M4 r+ z  B3 l    }
2 H; Q8 U) @1 A$ K" A- A}
% t4 r! r5 ?7 y1 V
6 ^; h: Q* A# @
$ W* Y) ^0 X* V3 A' Q) e4.执行一个SQL 查询,得到数据集(recordset)
( c5 K, M; o: L/ o% z# |9 R. i, ^: C* ]; p  J- {3 C# c
_RecordsetPtr GetRecordSet( LPSTR strSql, _ConnectionPtr ptrConn )+ m- w+ w8 Z8 W, P7 |
{
( g3 _6 e" P3 R5 v1 ]    try
9 v2 f1 z% f  \  L, U9 w/ o& _    {  z& r% M! ?5 M5 `( C: l
        RecordsetPtr ptrRS; // recordset 对象
9 c1 g' E) r$ S/ T% S2 C
( }) n- G5 Y) N7 v        // 创建recordset 对象实体
! }' D( l$ [9 |9 U  \        ptrRS.CreateInstance( __uuidof(Recordset) );. D" I$ }8 y) M1 ?/ j
        ptrRS->Open( strSql, ptrConn.GetInterfacePtr(), adOpenForwardOnly,
2 ^+ {2 b; @3 M+ ~adLockUnspecified, adCmdText );
6 H+ u* }' X4 [0 e, g' Z
1 j8 F; e+ v  W5 E- R        或者
% T& R5 H( x+ N, l! Z) S        ptrRS = ptrConn ->Execute( m_ strSql,NULL, adCmdText );$ ~$ I6 [( Z" l1 ?. j; I
        return ptrRS;  P/ J# _5 _% z) G( O' b
    }$ g+ H' y8 C) E' h+ g  ^9 |
    catch( _com_error & a_pComError )
" @9 X3 y+ V, C) `    {/ o5 w1 y5 g' E% l2 e' V4 c' Y
        ….// 错误处理( B3 v, Y* C+ [2 j
        return NULL;
! c) t* V8 S% I    }
# t+ N5 k* c* g2 k4 E1 \}
. x% ]9 i" p; h0 }& m* Z
0 C+ y" k! n+ n+ {5 E# M
% b3 x7 Y/ J! x) W( v5.通过数据集(recordset)得到列的名称
7 V. i9 J% E+ B* s- J# V$ Z2 H0 C# @6 }' R& I
HRESULT GetColumnNames( _RecordsetPtr ptrRs,        // recordset 对象
) [* S/ ?: p4 J# l) }                        char strColNames[][255],8 {3 f7 ]6 q: t) G
                        DataTypeEnum iColTypes[] )
6 r# I9 {- a4 z/ c) J{
/ E" x3 Z0 `2 V" U: J" k! ?% y( f    try. p) B+ s# ]- }. l
    { // 参数变量
; o3 ]0 o3 `" }        _variant_t l_vaIndex;
& t. V5 q+ w, w, n0 U
: m6 `- D, j6 {: O- |        l_vaIndex.vt = VT_I2;: G- w) F- ?  P) Y) x1 I/ M' X

* \+ m/ J; e- ~9 m        // COLUMNS总数4 I+ }+ {. j6 N6 r7 f! W8 R
        long lColCount;
- k/ t, O7 q6 F5 [1 H% S  z, @2 w8 D
        lColCount = ptrRs ->Fields->Count;. x. x) Y! l5 q
7 H0 s% I5 y" T9 H3 F& }) X
        // 循环取得列的属性和名称
& ^. k) n8 L5 l8 L6 G5 o. P; S& |; s        for( int iIndex = 0 ; iIndex < lColCount; iIndex++ )
- V1 b" ?5 w* r        {
  u/ L1 R5 |: k/ f/ U4 R            l_vaIndex.iVal = iIndex; // 设置循环索引
8 C4 m& a, r- F: {3 J8 ~* t( T& }  x' n& x" {
            // 取得字段名称
; |  F( g; K2 Q. [& p            sprintf(strColNames[iIndex], "%s", (LPSTR)ptrRs ->Fields->GetItem(l_vaIndex)->Name);, P+ u/ S, q0 K% a* F- {3 e

1 x6 M" B! R9 U+ h- `            // 取得字段属性
  g& d3 ^1 e8 R2 R/ l7 E# [/ T+ |% ]3 _            iColTypes = ptrRs ->Fields->GetItem(l_vaIndex)->Type;
5 ]. B- {. b" I. s/ V" c        }' j$ N0 K# W" B6 \( W
        return S_OK;
4 K# u4 [/ `0 Y- N    }" K* L! q& [% P& Q; [  |" x
    catch( _com_error & a_pComError )
5 `1 S% C9 k6 W/ i; F+ x+ _& h: H- X    {
% S8 \& |  i5 I. n* _        …. // 错误处理
  C. _2 J9 P9 w! X. V6 L  }( |        return E_UNEXPECTED;' V6 }! N7 l3 H- c) N+ V
    }& _1 F9 J* [  r+ J
    catch(...)
2 y  B, m! @1 q. \  b2 ]/ x    {5 I* E3 k. L, ~& b* g/ u. K) d
        …. // 错误处理
0 }  q7 Y) L, _1 B3 r4 T        return E_UNEXPECTED;
" u8 |: v6 g! ?' G" Y5 _* B3 ]7 t    }
$ h2 M# P3 Q& {* q, ^}
6 q- m4 c( @8 _# @1 j. T6 x1 q. B' ~( E  t' X# G* r# p

% r  I+ R- w9 {. }' ~: Z' g6.通过数据集(recordset)得到当前行记录
" v1 O! A9 p: I1 {
; ]& I3 G7 d" qHRESULT getOneRecord( _RecordsetPtr ptrRs,1 }) f/ B! I0 Z7 G$ {) q- n% p
                      const long lNoOfColumns,& z& r* _4 D' O5 T# o& Q7 A
                      _variant_t varValue[] )% N$ F1 W( y$ y) y. ]- K! f3 [
{
7 _( w. B; _  ]8 I. z    try
3 h' S& B. n# |    {
. d' @8 J3 y/ k' W! ^        // 参数变量. X1 P8 {( E1 w9 h# D4 I7 k
        _variant_t l_vaIndex;
4 J! L; Z+ [/ z6 C& J* J        l_vaIndex.vt = VT_I2;( g+ Q; t# ^. e! f4 L

2 S3 e; g5 ?  R# ]' n! g        // 循环取得列的值
  r3 \/ k# d& V& _! H+ z6 J        for( long lIndex = 0; lIndex < lNoOfColumns; lIndex++ )
6 \( c. ~* z" m- w/ h        { , M; P, ^; u! x% x- j
            l_vaIndex.iVal = lIndex;% [9 D, z' P, @

: z( V( l! p) D. @            // 取得字段值
; i0 t5 U/ v/ X) f: ?7 J8 l% d8 L            varValue[lIndex] = ptrRs->Fields->GetItem(l_vaIndex)->Value;
  P$ z! j, b' I7 B9 j        }
! |0 B/ n% U4 U7 p! F        return S_OK;
! h# k# ^' z. {; n8 F    }
5 j) e. Y! w/ I    catch( _com_error & a_pComError )
" J& v$ P" ]& P    {$ X  _0 \: K# B* B# H
        …. // 错误处理
, H  a; H2 t/ M7 H1 C+ |% U4 w        return E_UNEXPECTED;2 ~. k( I" g2 o' Z( ?* E( o% z
    }9 s3 o* b/ E4 ^1 B( C
    catch(...)
" j/ s+ O* ~& E( @0 j" ^    {
' z# Y+ K, t- K; W0 u: _        …. // 错误处理" T7 r& g& i0 X: C" u, x3 n+ u9 l6 |
        return E_UNEXPECTED;' X' @* \. N2 E& e8 L# ]
    }
' Q( b& W0 [% b2 D9 t}
1 u. H5 @: n8 R
4 _. h3 ]" N4 f+ C5 i+ k- O7 `8 v. x6 n
7.出错情况下错误信息的取得0 X0 M+ N' k% D
* _7 [1 W, b$ `  w$ s8 B3 Q
void ErrorFunc( _com_error &pComError, _ConnectionPtr ptrConn );; g( n1 o; N- s  i' X
{
# u2 p8 `2 l7 z4 e4 q  p    // COM 错误取得2 t4 d, b. r) }  e% h* e+ v# Q0 @/ _
    // 当执行COM功能的时候,如果出错,可以捕捉到_com_error的异常
+ o2 C/ Z8 u/ c  b! ^    char lpComErrorStr512];
- G7 z- D/ R- x% d) {- f& B, C$ D) K2 s( l& |/ R8 X
    sprintf( lpComErrorStr512,
' \) [; a4 S: N, J* K1 ^5 G             "ErrorCode = %08lx \ Error Message = %s \ Source = %s \ Description = %s ",
+ {* d/ W. `# R+ W             pComError.Error(),                  // 错误编号7 x+ U0 b; x* p, O- l
             pComError.ErrorMessage(),           // 错误信息
4 c) F, s' Z7 q( K, n             (LPCSTR) pComError.Source(),        // 错误源
' B+ N7 S- m9 `' C1 ]2 O; f$ Y* ]             (LPCSTR) pComError.Description() ); // 错误描述
" m. K) l( i. a) S0 _3 n% |9 t" a) e" c
    // 通过上面的代码我们可以看出,_com_error对象中可以得到COM所有出错的信息' ]3 W( H3 \1 }- i2 z4 n
    // ADO错误取得% d% v" o* [- ?
& [5 }3 g( f9 V% }. j9 Y( K0 i# F
    ErrorPtr pErr = NULL;  ]7 O! e- x: g+ j
    if( (ptrConn ->Errors->Count) > 0)
5 h. f" [% o" I- U0 R7 Z! j    {
3 i! K  G) ^) ]        long nCount = ptrConn ->Errors->Count;
8 w8 R0 w# y  q# `0 U        for( long i = 0; i < nCount; i++ )
  Y8 ~' M) q& E5 q; @2 D! S( H" b, P        {
& {& a- o$ M. W# a% s- X. @/ {            pErr = a_pConnPtr->Errors->GetItem(i);3 D$ [9 n* F9 }- u5 n7 _5 E9 E9 K

8 L' }+ n* n1 D3 E7 K            char l_pchErrorString[512];) x! R! |, r, V' q9 V) o
            sprintf( l_pchErrorString,"Error:\n Error number: %x\t%s",! @; \; u9 L1 p$ C" d- q
                     pErr->Number,         // 错误编号7 T! m, k+ [8 V% Y6 a' l3 B5 v+ F
                     pErr->Description );  // 错误描述  ?* v  X# c+ _& t1 j, D; \
        }
7 \! z! N% @7 y% s) ~    }
* @" {" _$ z( E6 d: Q! l+ M4 V- f3 e+ ~2 S& W  W8 x" p
    // ADO 处理出错的情况下, 在connection对象里面都有记录,可以通过访问  L' l! f9 _; b. J3 J
    // connection 对象取得错误编号和错误信息。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-14 18:11 , Processed in 0.018865 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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