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

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

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

' G( f5 i5 ~2 X1、 用import导入ADO 的 COM 文件msado15.dll3 {+ A4 M$ ~& w
% B' S2 ]3 c* t2 |8 s, b, G
例如:
, w# @, D6 G) W8 X' n
9 p/ J# r) y4 n' g5 Q  #import "C:\Program Files\Common Files\System\ADO\msado15.dll"\
& s( l  R3 t# J$ ~+ p+ ]. Q" g0 h
   no_namespace; S. {9 v/ k1 d5 x, e
3 T2 |  x2 k  z

# A- V4 L$ E" L% s2、COM 使用时初始化
, }% ~7 i# i8 Z( R
/ c& X1 y: s, h; kHRESULT ComInit()
/ I: W. o: a5 t( d2 {' a$ `( p{ / h2 z3 b! |9 m6 L! O
    HRESULT hr = S_OK;             // 默认返回值/ I2 l) m9 S' U
    if FAILED(CoInitialize(NULL))  // COM 初始化调用  y% I) C: u) i; T1 S7 j# {
    {
8 P. h; M( t. |2 T+ c/ `3 l' P        CoUninitialize();3 }0 K6 P) H! H3 o
        hr = E_UNEXPECTED;
" B8 g- D5 }7 C4 w7 X- p    }' O& W# V9 v. e; u" @' w6 L
    return hr;$ y* b9 `2 n, |* L
}; X9 C# M, R5 r% N

! L4 Z- ~9 e, W4 X. S+ L9 x1 D* A" X" A
3、建立数据库连接
/ [0 R2 ?5 ]0 Q+ }5 L& Y$ `
( D% H+ ^( T( F, @HRESULT ConnectToDB( LPSTR pUserId ,                    // 用户名
( f' a$ ]/ S3 J* h2 f                     LPSTR pConnString,                 // 连接字串
; r  ~# W0 B0 ], F  k" p9 P) H7 V                     LPSTR pUserPassword ,              // 用户密码8 E4 q# A3 l, {- A2 M
                     ConnectOptionEnum ConnectOption )  // 连接参数
0 O" b) U" b! c( n{6 w# K8 f% `9 z9 v; @( s3 @4 E
: q. S6 H# B5 s1 G
    HRESULT hr = S_OK;        // 默认返回值% r" O8 n7 N! r. J  E
    _ConnectionPtr ptrConn;   // 定义Connection对象1 R" J! h4 {9 \# N4 o" m
/ u' S6 m) Y  U! l) Q
    try
7 R7 N7 I) O  x. I# ~3 |' u: E3 D    {" e# D# F+ B) w8 a' F! t
        // 创建一个连接实体
7 S' U! Q5 ~- g9 J1 w: `        hr = ptrConn.CreateInstance( __uuidof(Connection) );; r, R9 b$ {; C0 g- ~, c& W0 ?

1 R8 H* x6 F+ F# S  M0 Q        // 设定连接等待的最大秒数,默认是15秒( ~" a" @6 X" [" e% v8 t
        ptrConn->ConnectionTimeout = 20
/ |9 \" U. M  d  P! k" R  o) V) N
        // 打开连接5 W/ ^5 m% A; A( Q0 S
        hr = ptrConn->Open( pConnString, pUserId, pUserPassword, ConnectOption );! H" ]) }8 q+ T5 R. g0 B" G
        return hr;
) e5 w! J. ?5 I( U    }# v% V7 Q" a9 g/ A
    catch( _com_error & pComError )5 H5 s7 v: ?4 H) O, t# V
    {& Q: Y6 H2 _0 I0 k+ ?. J4 @8 d
        …… // 错误处理$ u( N& V2 R% h# n
        return E_UNEXPECTED;% N* J& F8 N5 P( g7 B8 f
    }8 H' j+ f  X; e- e8 n
}
  r0 J7 X$ L. @' v8 u! \
( N+ T) U3 z5 s6 n/ J) l
' q$ N# ?4 \5 |: Y+ a0 s4.执行一个SQL 查询,得到数据集(recordset)
2 a2 z% H: k( X/ `
) G& W4 m& o: o/ k, _6 C_RecordsetPtr GetRecordSet( LPSTR strSql, _ConnectionPtr ptrConn )* C- M  s# p" u; Y+ }# N. h
{
7 W! g. Q3 T5 S3 c0 X( a, a4 |    try
9 c  _7 v" @$ Y    {5 ~" b& n  w6 n/ z$ V7 Q, m+ k
        RecordsetPtr ptrRS; // recordset 对象2 M" k4 I' a6 y: a: J

( M  K- y: o; W% Q- e4 x: N        // 创建recordset 对象实体
! {6 @5 w- c3 o! V, {$ F* M, @- l        ptrRS.CreateInstance( __uuidof(Recordset) );) U- |" T: _  ~+ n! E
        ptrRS->Open( strSql, ptrConn.GetInterfacePtr(), adOpenForwardOnly, 7 F5 n6 c. {  j; Q# J
adLockUnspecified, adCmdText );+ g1 n" w) [; D, b2 T
$ L: {% C6 \; S- f& |$ _. k
        或者: a7 g% }; \5 v0 J/ G
        ptrRS = ptrConn ->Execute( m_ strSql,NULL, adCmdText );
/ `/ h* k! U+ M7 [) a" ~3 \        return ptrRS;
/ h$ K2 E/ v0 c  h7 C- h, \" V+ N    }3 ?! Z5 s+ v/ \1 o) q
    catch( _com_error & a_pComError )" m9 Z  K- x, z7 l
    {+ W2 H; q2 y+ i: ?1 r+ j8 V
        ….// 错误处理  X6 A$ D/ x- Z+ e) j; u5 r1 s
        return NULL;
. ]) F8 v: L4 J3 k6 o    }$ G6 L$ w/ G$ @
}/ x/ V: \" [- U9 ^5 y8 U

$ @, @; S! r) ^  Y9 [+ R5 F' r! \' L  a. b) z
5.通过数据集(recordset)得到列的名称5 Z, O! x( {8 x  p$ h( W
; i( y) T5 B7 |8 R+ E( [
HRESULT GetColumnNames( _RecordsetPtr ptrRs,        // recordset 对象
3 b% L0 C& W$ G                        char strColNames[][255],
6 {) \! W6 e7 O* w4 ~% U+ @                        DataTypeEnum iColTypes[] )
2 o" `/ p) q- {! }8 A# d1 z  [{# |' `$ j" [' z
    try
7 \4 y8 _# L1 Z    { // 参数变量
- E' n7 j4 O5 i* S3 J9 E9 L# C' \+ d        _variant_t l_vaIndex;8 C3 |8 @5 @2 F; M- f

% S! \. {, o2 W6 {% B, L& C$ P$ [        l_vaIndex.vt = VT_I2;9 M) m6 _8 L; ^% W  z" B0 \

$ \5 a  F4 k( g. n        // COLUMNS总数
* j6 p; }/ {( s        long lColCount;$ y7 v! n6 p: y- {. ?
9 {8 n4 J; h8 V4 @; I5 J* t
        lColCount = ptrRs ->Fields->Count;
  K4 X  B1 O+ r: W" h' V/ D4 D0 r9 g3 I3 C  A2 C( O: s9 c
        // 循环取得列的属性和名称, {5 b$ J" r0 f6 o1 h8 x
        for( int iIndex = 0 ; iIndex < lColCount; iIndex++ )1 j1 o6 O5 k( G
        {
; z2 B/ g0 U7 B5 B; ]1 N. u1 E' A            l_vaIndex.iVal = iIndex; // 设置循环索引
" E/ y% E) I' u) n" k9 j' D1 p% ^
; K( E! A( s5 y& U: ?( J& \            // 取得字段名称8 p* b' i: L  L: d" f# E3 y: [
            sprintf(strColNames[iIndex], "%s", (LPSTR)ptrRs ->Fields->GetItem(l_vaIndex)->Name);
* |7 X& p) F# A* d. j  n( A9 a
& l+ F# [1 Q$ Y& Y4 a+ X! i: M: |            // 取得字段属性
& \& N# W- E* c2 y' ^" b) P( y            iColTypes = ptrRs ->Fields->GetItem(l_vaIndex)->Type;) A1 M* p( {! r+ e
        }5 C/ F: C$ ^: y5 d* t7 v8 n0 ^; Q
        return S_OK;
" G+ V& W0 P, v! U' [    }& f* H& m' w* n2 v/ i3 E2 ?6 a
    catch( _com_error & a_pComError )4 g' q! _! B" X. X& n3 [% _6 a
    {
/ d6 e/ Q6 \# M5 [        …. // 错误处理
& r! m3 |) y* b        return E_UNEXPECTED;  D2 \9 q  t# C- H' p
    }" [  `: d) _( E7 B  c) z3 _$ x
    catch(...)
3 l; C* q4 B8 ^1 Z" Y  [, E    {
7 A$ t! P) h! f# q- E& w8 [" G% Z        …. // 错误处理+ m: b+ M: u. Z6 y& P' n3 H
        return E_UNEXPECTED;; c0 k3 n: M2 f! e" u8 S# Z
    }. y. b+ l7 e8 b) C8 N" A# l
}1 D# s2 Y5 T; V  ]: A2 X/ _: @

/ a9 }6 B* x9 q! L9 K# ~6 i* L/ f3 z7 D$ [
6.通过数据集(recordset)得到当前行记录
4 s+ c: J, ?4 q8 V; x: N$ F
9 m* o& ^; |7 p) DHRESULT getOneRecord( _RecordsetPtr ptrRs,& G% K1 }- K6 B' c
                      const long lNoOfColumns,
& ~* u" y9 H! x                      _variant_t varValue[] )7 y# q/ w( X" n+ b+ k" L
{
3 P5 H' o, B) _4 G) C    try. K( O% q' |2 V; X
    {& L) f* L3 T% L
        // 参数变量
) E+ n( v4 B; x        _variant_t l_vaIndex;
5 e- k) n* Q( v' `2 t        l_vaIndex.vt = VT_I2;9 Z  f3 T2 g* m+ v6 o! t" C
" x# c+ ?( H9 y- e; A
        // 循环取得列的值5 ?0 _$ ?7 j# v
        for( long lIndex = 0; lIndex < lNoOfColumns; lIndex++ )5 J' E- o- g5 }& \5 N# e2 g
        { - \! c! o% Z9 j7 y+ ^. A* ]  [
            l_vaIndex.iVal = lIndex;; h4 W, F- O0 W) a

* |! K* X* b! B6 G7 ]; S9 a            // 取得字段值9 g7 i" N0 h3 H/ A  ~5 ^/ B
            varValue[lIndex] = ptrRs->Fields->GetItem(l_vaIndex)->Value;
  O& i$ G% |3 a$ F# o        }. n# y9 [# p; S8 J5 y! |9 b" Z
        return S_OK;
, l. U; @, R& H+ v% O% F    }* I/ J- M3 y+ x" P
    catch( _com_error & a_pComError )
" v, e( \9 s# z" e5 z    {
2 i4 o0 O; ]% O* s, h6 d        …. // 错误处理
  r8 [6 z  r2 r) `) \) j* V( i        return E_UNEXPECTED;
, h, q4 M: h+ e" Q" m    }6 F1 k9 Q, [8 u
    catch(...)* S" ^7 J3 O' M7 F, _
    {
6 S4 o& U+ t! N% r        …. // 错误处理0 F, v5 }0 E; K. I3 U
        return E_UNEXPECTED;
, q2 ]) d3 O. v    }
' ^, _/ q, L5 _# k* V( k}
. `. }/ P/ {. z  x: N3 [
6 Y' t( q0 \- W
- e: l6 l% r5 O) ]: C7.出错情况下错误信息的取得
( S0 M( p5 q% k0 N: g2 T0 D" a9 @$ a% i0 V, X) D  a1 l
void ErrorFunc( _com_error &pComError, _ConnectionPtr ptrConn );5 H7 ]" g# s5 }  k' l
{4 G6 M8 I1 Z$ a# Y( y1 N
    // COM 错误取得
( z' t4 v9 a) ^$ C    // 当执行COM功能的时候,如果出错,可以捕捉到_com_error的异常$ Z/ ?& u+ p5 X( Z9 Q
    char lpComErrorStr512];0 ]2 j3 r$ O4 m# U

: M+ V( K  |8 y2 z$ o; S    sprintf( lpComErrorStr512,
1 c0 k% |$ Z% [9 v& B             "ErrorCode = %08lx \ Error Message = %s \ Source = %s \ Description = %s ",
% a4 m# P1 d$ G* i; i             pComError.Error(),                  // 错误编号
/ F- H# c; X$ M" s/ B             pComError.ErrorMessage(),           // 错误信息
: i9 }( |) @5 V) K# X* N4 \0 G/ n             (LPCSTR) pComError.Source(),        // 错误源
; y" ~1 B/ D( B+ O" A8 n$ a$ S2 S             (LPCSTR) pComError.Description() ); // 错误描述
, z4 e! j) X5 i3 \& W" e, B2 V( J0 P' X- r/ U: T
    // 通过上面的代码我们可以看出,_com_error对象中可以得到COM所有出错的信息% {  J5 t- X8 n9 `6 J4 `) D4 c
    // ADO错误取得
# \: M0 d: @3 i6 E. X  l
( v1 k: V6 K* g' J    ErrorPtr pErr = NULL;7 `) y: S' {. y* e; n
    if( (ptrConn ->Errors->Count) > 0)$ a) K: U, c/ o/ r1 n2 W$ d
    {; f& r8 {1 M1 H6 J* z
        long nCount = ptrConn ->Errors->Count;
1 z6 M& v) L9 @  S; x        for( long i = 0; i < nCount; i++ )
* ?% h# W3 ?/ Y) n1 O8 Q. [+ S1 n# ]        {5 W: i( D, n0 _1 c- G
            pErr = a_pConnPtr->Errors->GetItem(i);7 L" x& I$ c% ]
  F! u6 i. \# E  i
            char l_pchErrorString[512];
" v+ ^2 x$ q, Z8 V            sprintf( l_pchErrorString,"Error:\n Error number: %x\t%s",0 [/ n* K$ f) Q% V9 ]' C
                     pErr->Number,         // 错误编号
- A' z4 [% _7 L; i                     pErr->Description );  // 错误描述
* y& X0 A; F1 h# s3 _4 A        }
0 E# C% l: I( ~, G' N    }; D0 s% |( p9 X' {
  K$ C3 \+ D. m
    // ADO 处理出错的情况下, 在connection对象里面都有记录,可以通过访问
) q# N8 o5 U6 d; {+ i& l    // connection 对象取得错误编号和错误信息。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 12:17 , Processed in 0.018538 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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