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

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

[复制链接]
发表于 2004-1-31 18:14:29 | 显示全部楼层 |阅读模式
  对于在WINDOWS上编写数据库程序的程序员来说,ActiveX Data Objects (ADO) 是最常使用的技术了,通过ADO可以简单的实现数据库的连接以及数据访问。但是在VC++中使用ADO时,却因为是使用COM的方式来调用,常常出现一些系统无法编译通过,或使用中程序非法出错的问题,在这里想大概介绍一下VC++中调用ADO的常用方法。
# R8 N3 h" \8 k0 E7 d1 n
2 x. Z1 t7 d1 W5 L+ j1、 用import导入ADO 的 COM 文件msado15.dll
& y" t3 z- v# F8 N9 P7 z3 B
$ v/ M8 k: s6 n+ S  z! v例如:
. G6 F) E/ v6 r: u& L+ W1 W8 f; d- h/ r3 J- C
  #import "C:\Program Files\Common Files\System\ADO\msado15.dll"\5 V) U7 Q, ~) @6 f
$ a* X0 n% }1 p* K1 z+ @* R
   no_namespace( m2 J; T) _% t" l

& |2 z& s7 H+ u+ s1 x' k5 b
/ ~7 a; |, F2 d! X# H3 W! p2、COM 使用时初始化
% G/ `& b3 q  g- U8 c. T
! c0 F: F& e" m% @% Y9 GHRESULT ComInit()* k1 I* M! T6 b5 X
{
! T: y* x9 g6 f1 Y- f, c: r6 b    HRESULT hr = S_OK;             // 默认返回值
3 G+ i/ O: e: Q    if FAILED(CoInitialize(NULL))  // COM 初始化调用# X) [4 j- r0 }
    {( ^5 z5 @' q5 |& @
        CoUninitialize();( Z) Z6 @; u. x9 t' T3 G
        hr = E_UNEXPECTED;
7 t" \1 p+ ^% w: E/ D; W! v    }
. K. ?2 f% ~+ {* ]    return hr;" ?. b, f3 k4 x7 p
}+ K* O. Z: l7 S
7 U0 c* J5 I* \/ U& k
7 M2 v7 \- e. @" C9 ?6 X- [
3、建立数据库连接
# P2 c" j* ^0 p1 Q
* v2 X4 k6 t; X( q, X0 q1 }+ AHRESULT ConnectToDB( LPSTR pUserId ,                    // 用户名
. q5 g  u( o1 V. R8 Z3 q                     LPSTR pConnString,                 // 连接字串 % ]1 C- w) K. f, a0 N& o, c
                     LPSTR pUserPassword ,              // 用户密码- L1 c& T' ^; s
                     ConnectOptionEnum ConnectOption )  // 连接参数6 L$ }$ F. ~. d
{/ A. p2 {$ G% B0 b0 Y, y+ G

5 q7 f" U* ?; e    HRESULT hr = S_OK;        // 默认返回值
- p5 V4 ~9 B7 J! d. ~4 ?    _ConnectionPtr ptrConn;   // 定义Connection对象8 j8 u; @7 C; k: {$ o

1 A$ K; s. R/ E7 T9 R    try
0 W- W" Y. H. [7 e9 U* Z    {
, q0 L1 M2 E9 f! \, Q5 c        // 创建一个连接实体1 _3 n9 U$ j; l1 q. V3 E
        hr = ptrConn.CreateInstance( __uuidof(Connection) );
6 P$ F* u4 M& O
6 |/ l! h/ f  E) I        // 设定连接等待的最大秒数,默认是15秒- j$ Z% R- Q4 V' x3 `
        ptrConn->ConnectionTimeout = 20
6 G( S; O# T0 f0 i! \6 s
" V4 f  C  H0 O/ J' t1 L* c; u        // 打开连接, a  A1 u$ C% g3 ?0 A
        hr = ptrConn->Open( pConnString, pUserId, pUserPassword, ConnectOption );( u% U6 a4 r8 ~) L) [
        return hr;* A% s0 h3 p' Z6 Q# `. m( f
    }. a- Q4 H6 x2 |
    catch( _com_error & pComError ), Y; m) B0 E7 A
    {
; T6 o" |4 S9 ~" @( j        …… // 错误处理' e$ a' s) X; L2 r$ U. z1 ?
        return E_UNEXPECTED;
4 j5 Y* `; N- g  O; p    }/ o/ M6 z. s, L; U; y1 F
}" T+ z8 y7 l* u- w$ r. D
! E6 M( M( [  P9 u  w6 i
( ]% l+ e  l0 u1 l+ v  N
4.执行一个SQL 查询,得到数据集(recordset)
$ _! ?- q0 r; u# T; R
7 T, J' T# H7 D* M$ ?_RecordsetPtr GetRecordSet( LPSTR strSql, _ConnectionPtr ptrConn )
7 [( n. k) e& K9 ~. ~{
! I+ y) X! L( n& L* x    try
3 ~! G7 Y" A9 v6 H" K! e0 ]    {
( L) R3 d, `, d* Q+ H  U3 U; F5 Z        RecordsetPtr ptrRS; // recordset 对象6 d0 E" _2 @1 _$ g
! z" c5 }& p& k; T5 A
        // 创建recordset 对象实体
# {/ d, o$ [, Y  x0 \        ptrRS.CreateInstance( __uuidof(Recordset) );6 O# s5 [% ?+ g2 Q* \# q
        ptrRS->Open( strSql, ptrConn.GetInterfacePtr(), adOpenForwardOnly,
' }  O1 C0 W  f$ c* zadLockUnspecified, adCmdText );2 p0 t8 H, J! n" N) i
9 L2 P* N+ Q9 [) w) U
        或者- F* l/ A+ D. \: W7 [
        ptrRS = ptrConn ->Execute( m_ strSql,NULL, adCmdText );- m5 d6 h  b' W9 o
        return ptrRS;- j, R3 [1 l2 k& l- T% B( I( e
    }
* d, h* `6 m  {    catch( _com_error & a_pComError )
; [$ i3 e. p3 O# B# b& Y9 n    {+ U) g) `2 P  m0 s) [
        ….// 错误处理9 N8 \, n% @; J6 Q" A5 e
        return NULL;
) E& G% y7 K6 @: N    }
7 e! g. {) L+ J( p7 R}
# w  M& u+ J$ \7 }% i; x6 g! F* y: y( o1 W5 q! G0 S

: V& k, g  U8 z# X2 O5.通过数据集(recordset)得到列的名称* P" @$ A: t# v' X' v- q. j
# H: @& k& F6 F1 v% t7 D+ v
HRESULT GetColumnNames( _RecordsetPtr ptrRs,        // recordset 对象0 V- U; O5 s! |* v3 ^) Z/ |$ U
                        char strColNames[][255],
- g7 \4 j- y. j2 Z5 Q. M                        DataTypeEnum iColTypes[] )) G: v+ ^5 r0 W- M- f# f
{0 G, k" D8 c( i6 n: a, p5 u
    try- d; m  v6 ^: q& `7 ?! v9 [* W
    { // 参数变量
, r8 ^: G2 v' t        _variant_t l_vaIndex;+ @; T: w, l- a8 {. j3 S

: j" I4 t& F8 N2 v: ^        l_vaIndex.vt = VT_I2;: p- Z" d6 Y0 S' Y
8 i+ Y3 I! L% _0 L# y3 O
        // COLUMNS总数
5 E/ M) h2 O8 t, T        long lColCount;
/ r3 `2 p) \) K: [
% Z8 g9 F( P) _. i# X8 T3 l' O+ L: u        lColCount = ptrRs ->Fields->Count;
5 T, O8 ~" A! M7 c9 p6 C2 t8 S7 q- S/ i4 J% b) r% D% W' [
        // 循环取得列的属性和名称
9 g: I; g. W) z) _" A7 P( l% J& I        for( int iIndex = 0 ; iIndex < lColCount; iIndex++ )
- g6 r2 y# t/ T' {9 w% w        {1 o8 t2 c' b3 h& I
            l_vaIndex.iVal = iIndex; // 设置循环索引. [" z. o- o) P) q

( n# J8 S% \! [. H, ?            // 取得字段名称0 D7 N- o6 D/ ?' N1 X! B
            sprintf(strColNames[iIndex], "%s", (LPSTR)ptrRs ->Fields->GetItem(l_vaIndex)->Name);
3 f% C& ~" H+ ]+ V, y2 Q% H( B
& r7 f0 a/ x  v  o$ h9 Y  K            // 取得字段属性
% t! `# [* N2 Y( U5 x4 b$ G& @; g            iColTypes = ptrRs ->Fields->GetItem(l_vaIndex)->Type;$ V0 ^" L4 J; b& l
        }/ Q4 z3 Q% s$ \5 S
        return S_OK;0 L7 u% U0 ^5 ]% @
    }
* {4 a' Q, C9 Z5 m+ v# k    catch( _com_error & a_pComError )( W! p! Y; t1 K$ G
    {
+ E6 S7 f% C$ y) Y# @        …. // 错误处理& x1 D% Y. _) c% \! S' y9 P) ?
        return E_UNEXPECTED;
$ [6 u% y( |; E. A& g    }) |2 J% h) H  Z6 T
    catch(...)" q  g8 C6 x' W
    {+ S4 c; K, ~5 X: Z+ q! i
        …. // 错误处理5 H* q& J$ [3 {7 ^/ O" @! v  e
        return E_UNEXPECTED;& [( p9 _& ?# N  f7 G7 {# @
    }7 b/ I% p! }) F* Z% g
}! [+ C4 R  w0 U& c0 R

, M$ ]6 a- q: N+ b3 g7 @4 k: I3 T2 c8 d# o$ f$ J6 d" |
6.通过数据集(recordset)得到当前行记录9 R' |+ k3 o# D8 T

8 o/ q+ k" `. c; d9 M2 pHRESULT getOneRecord( _RecordsetPtr ptrRs,
  _. c' B( r+ }7 P. H                      const long lNoOfColumns,
8 ]3 X1 |" F8 |7 v2 d3 |! d                      _variant_t varValue[] )& l, Z# X3 r) ]( ^' z" O( _% h
{$ O- Q( K8 E3 e. L4 n6 K
    try6 V' ]: j: U. i: J( V
    {
, @# n: D8 M' @        // 参数变量
& Y7 G( A% f6 ^6 P; Y        _variant_t l_vaIndex;
2 O) f- h, K5 P* m; M$ E        l_vaIndex.vt = VT_I2;
( X1 A# |4 y) Y3 W! q1 t1 V# ]5 l
        // 循环取得列的值! O0 x& m8 B6 Z/ w7 J
        for( long lIndex = 0; lIndex < lNoOfColumns; lIndex++ )
" X. A$ a$ }3 v! C) |! C$ y8 i/ y        {
1 X) E- Y, P" y4 m! M. \# F; W) ~/ k& {& y            l_vaIndex.iVal = lIndex;! u$ w1 K5 e/ ?) ~2 S
7 Z% }" J7 r8 |( R
            // 取得字段值6 g3 N9 w  z7 Y* b' E
            varValue[lIndex] = ptrRs->Fields->GetItem(l_vaIndex)->Value;
6 p% b, P' f0 c! Z( g) }2 D) b! n+ S6 U        }) ~7 z3 c: m0 |
        return S_OK;
3 l5 k0 i9 {! ?  Q5 P+ i    }
3 X1 r* T3 r; j0 a+ K: I$ T    catch( _com_error & a_pComError ), L) {: G2 G/ Z# @
    {: s8 z' n% o# s& ~1 ?
        …. // 错误处理
3 q. y1 O; C% ]6 ^  V        return E_UNEXPECTED;
% {5 T% L9 v% N: Y$ ]0 a    }
+ b6 q: l3 Z8 O% Z    catch(...)
! w2 U4 e6 `' V) ~+ E& b2 f    {% n$ z7 m0 a* ?
        …. // 错误处理6 `; ~0 G" g- w
        return E_UNEXPECTED;
  Y( T4 h; y1 o  V  w    }
  n2 F5 s% T# Y) n; z/ x5 E4 P7 X}) |& w9 `8 W" Q$ b! G
* y$ W3 ?7 l0 f0 q. D6 F3 W

$ x4 `& n6 |; F3 o7.出错情况下错误信息的取得
8 _/ e& U+ `) T0 Q* o: E3 o
4 T) q, m6 S7 h3 \; xvoid ErrorFunc( _com_error &pComError, _ConnectionPtr ptrConn );
- B% X8 S5 r: p6 i5 K: V3 z0 `' h{
+ N$ l+ Y* d/ B    // COM 错误取得
9 u. S7 O' o; I: J$ z    // 当执行COM功能的时候,如果出错,可以捕捉到_com_error的异常3 a+ l' Q7 Q* {) C' U+ G
    char lpComErrorStr512];0 w, j$ Z' U2 [- I

0 d, x$ S1 I' a& j; P    sprintf( lpComErrorStr512,9 i4 Q1 J2 l3 }: l5 t
             "ErrorCode = %08lx \ Error Message = %s \ Source = %s \ Description = %s ",
9 F2 N2 e& n' g8 K4 y0 e" f             pComError.Error(),                  // 错误编号9 n) n7 d. w0 W# R
             pComError.ErrorMessage(),           // 错误信息5 z  p0 G" X0 ]* T1 K/ w5 l* `
             (LPCSTR) pComError.Source(),        // 错误源
! D* v" K+ j0 X# Y* M- ^             (LPCSTR) pComError.Description() ); // 错误描述
5 ?4 C- m. d: p5 G1 K$ X- G! p% w2 N+ {
    // 通过上面的代码我们可以看出,_com_error对象中可以得到COM所有出错的信息
9 [3 R; {, ?$ T: ^  `    // ADO错误取得' e: F' U% u6 p. W& @1 o# J
6 i9 {. Y4 Y9 h3 j, E4 I3 ]  m
    ErrorPtr pErr = NULL;- }# P" s* K- i# N/ \; I  [
    if( (ptrConn ->Errors->Count) > 0)) O: D4 U' @4 n9 k5 i: ^
    {
$ W0 D5 ^; d$ d0 S& g        long nCount = ptrConn ->Errors->Count;
% Q6 H" V: T2 _; t% s* ]        for( long i = 0; i < nCount; i++ )
# c, B8 h9 f2 r# s        {
2 m5 `3 m# F6 E4 W* H            pErr = a_pConnPtr->Errors->GetItem(i);6 M2 N( m# w$ F& U' Y

4 H0 D) p3 S) S* ^/ ~/ g, E* c            char l_pchErrorString[512];
8 f0 X3 t  Z" @            sprintf( l_pchErrorString,"Error:\n Error number: %x\t%s",; o. u8 h7 f$ n0 u: c- C: t8 D
                     pErr->Number,         // 错误编号7 p4 g  w/ E! x7 K6 B2 p/ r
                     pErr->Description );  // 错误描述
* j% Q9 l4 r, p        }
8 W! q- ~; z9 B( C    }; v+ A& @& C0 B# L1 {* ^

: e3 _* X5 I# `0 F* V, U2 }    // ADO 处理出错的情况下, 在connection对象里面都有记录,可以通过访问
: s2 I& f1 N' v4 o9 y7 Z    // connection 对象取得错误编号和错误信息。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-19 17:52 , Processed in 0.045905 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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