QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3519|回复: 0
打印 上一主题 下一主题

[转帖]在Visual C++中用ADO进行数据库编程(中)

[复制链接]
字体大小: 正常 放大
god        

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集7 b: }0 X0 T! [$ P. i
2 [( N( j5 o6 r' h2 e  g4 h
  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;5 F( K. C) q- i% ^/ l
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
' P" H! z2 P5 K2 Y9 I* D- S0 s8 PSQL命令的执行可以采用多种形式,下面我们一进行阐述。
2 n0 @4 G4 `; v0 U% L/ ~# P
. i5 B, j7 h1 z/ V8 |! w: q  (1)利用Connection对象的Execute方法执行SQL命令" m/ ]: r+ x7 ?# c
, y/ g* w# L3 Z9 G
  Execute方法的原型如下所示:
) \( M7 D3 _6 E6 X+ u' V# Z8 t# U/ M" k6 g
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) , U- ~4 n# P: M9 h, _
7 {; b6 Q$ R3 @  {3 V5 u
其中CommandText是命令字串,通常是SQL命令。
. r" H9 h8 W. I1 N/ a! I参数RecordsAffected是操作完成后所影响的行数, 1 h2 M+ W) u* ]- Y
参数Options表示CommandText中内容的类型,Options可以取如下值之一:
. x/ U, f  ^+ a0 S" _' O/ oadCmdText:表明CommandText是文本命令3 w* ~& j- J. S
adCmdTable:表明CommandText是一个表名
* K& B/ `9 I) ]/ F* P4 \" P8 O3 AadCmdProc:表明CommandText是一个存储过程
* d! y; _) j: V5 L0 \# c! eadCmdUnknown:未知
7 R4 F# h: @: }
2 X( c* V4 @5 f2 YExecute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。 % n) d2 a+ D9 {) [8 ^) _
_variant_t RecordsAffected;: ~5 u5 b' a% m! ^# V  T
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday0 x8 F. }( @6 m/ Y
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",3 L) p9 Q4 @: B( i- b* r' I8 M' R$ \
&RecordsAffected,3 E& i3 Z8 k  t6 n- t
adCmdText);
" i  E7 g1 G( k$ ~8 x( T+ j3 V
' n& C* P5 }+ W' d( B8 }///往表格里面添加记录
  }4 N# u, d* ~0 r! Lm_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
  d* {& ?. ]1 Y& Z4 O  M3 Q- c& d# h% V# k9 T6 O; w
///将所有记录old字段的值加一. P5 j& Q, g' H
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
5 m/ s0 Y0 [+ k: I. J- b8 ~% I, C+ D+ m( k
///执行SQL统计命令得到包含记录条数的记录集) C  c% a( X0 j' h
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);4 D4 M* W0 e: L4 O
_variant_t vIndex = (long)0;& i" v. {& `# u5 ~" e
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量7 H4 g8 K2 Z1 L% G
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
% h" m$ o, x. D. ym_pRecordset->Close();///关闭记录集# q6 I0 @9 m* d& `# h
CString message;; ?0 j6 ^. W  P: T' H  t' |
message.format("共有%d条记录",vCount.lVal);0 z) \: H) @# t* O% z, Y: g
AfxMessageBox(message);///显示当前记录条数
$ R$ P4 S% ~" s3 x8 p+ L% }# D7 F  Y" D; m, N" f9 k* u
(2)利用Command对象来执行SQL命令 * ]# K7 P0 B( i$ T# z9 e; [$ B6 r
6 b. U" j- N% ^3 w1 Y7 i7 b1 S
_CommandPtr m_pCommand;
" B, {3 @6 p; U0 x0 |. A/ Sm_pCommand.CreateInstance("ADODB.Command");
+ U$ {9 ~& D( x: ]2 t$ C_variant_t vNULL;
' Z1 [' N. \  f0 p7 z( ?) jvNULL.vt = VT_ERROR;
% a% @/ \) \9 a0 N- _+ }- \- EvNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数! w' C; u1 r1 ?7 z& A
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它7 }( R' e4 J# f7 y
m_pCommand->CommandText = "SELECT * FROM users";///命令字串
7 h9 Y: k; S! \1 F- S" J2 Bm_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集/ \" Y, Q  u' m1 w7 J0 \4 N
9 u' ?* F1 X* N7 X4 {; `; ^9 k
  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
( {+ y. {" n5 ^+ f
7 M5 S' R, }1 w0 w0 i3 B  (3)直接用Recordset对象进行查询取得记录集
* s2 ^  j  s1 u0 f: y# H/ Y. [# V, B2 @5 D/ f! u8 F8 t% p8 e) w6 E
  实例——
# b# [8 U( V- C, D" A1 B
, @, ?1 F5 F# k7 I+ Ivoid CGmsaDlg::OnDBSelect()
7 u! V, S2 R4 j" s7 r& d) z# o{: z( A+ w/ n! J1 f# M; }  a. l& J
// TOD Add your control notification handler code here
( `3 [9 A4 \5 {) q8 ]_RecordsetPtr Rs1; //定义Recordset对象
# ^( R1 n1 i  ^3 ?_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串, w8 ^5 Z9 f/ @8 @- i9 r. }1 E
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句9 ]$ ?' \, i# v5 H$ r3 D
::CoInitialize(NULL); //初始化Rs1对象
4 K: h9 o4 U4 B2 c( }, u2 sHRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
  s0 d. M/ E. Y% m//省略对返回值hr的判断 % o) g* s1 x  r% d- _
Rs1->Open( Source,+ q  R! l5 p7 l, ?8 H) Y$ B/ o
Connect,+ d( {  _1 j" i7 E5 y
adOpenForwardOnly,
" |. s; N2 H/ f! U  G: F4 `2 z' RadLockReadOnly,
  d$ \1 T7 f' v, T: v; z-1 );
4 @+ b1 p1 `# v9 t_variant_t temp=Rs1->GetCollect(_variant_t((long)0));+ n# Z3 Z" Z, {1 z1 }$ i
CString strTemp=(char* )(_bstr_t)temp;
' N8 x  `: l! v  v) EMessageBox("OK!"+strTemp);
" }" N7 j2 }$ f4 ]}2 K- g  T2 T3 {( X
" O8 M  u3 I6 {7 B. x0 z
例如
1 W* Q$ h* w/ b6 M% p( C0 ]m_pRecordset->Open("SELECT * FROM users",
+ a( A1 d/ N! U6 i5 l" Q_variant_t((IDispatch *)m_pConnection,true),/ b6 m1 {$ ~& D2 E+ e
adOpenStatic,
0 |' f' \; z4 |* B( ~adLockOptimistic,
5 u: o: Z; b. `8 VadCmdText);
. t1 B/ M* H) w% t) ~' K
4 W" v) w) H3 b* H3 h: BOpen方法的原型是这样的:! H4 e. z0 x$ b3 p! M3 J* B
HRESULT Recordset15::Open ( const _variant_t & Source,
, P% p) R3 L. P  c0 V2 s+ O' r: lconst _variant_t & ActiveConnection, 5 U' D- T" V8 a
enum CursorTypeEnum CursorType, * m, c- O' L% [) |$ {, ]
enum LockTypeEnum LockType,
* T7 ?( D* ]3 }$ e3 C: Along Options )
; E1 t! {7 k; R; j; ?) `  P: o) T( x/ \  r
其中:
) e& `6 F+ ~- {- X5 y. o
# a5 P8 q+ z( P1 M①Source是数据查询字符串: u  {" a; m+ }) ]$ I9 h7 }
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
+ V9 ?& w9 W. C$ ~③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
. t' L2 e& V0 q$ \  q4 i! T* Q: g* [6 _7 r' L2 m8 A
enum CursorTypeEnum- d7 \! `5 |7 Q8 ~
{
4 f- C9 j. O; I+ u' E+ q7 s" F: u# madOpenUnspecified = -1,///不作特别指定
# h0 x& S# Y% {. kadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用- X) {$ l2 d9 Y0 Q
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
7 h" T4 P* d# K! D4 V% F! _! F! E
! {: e. a( R& X+ [; z. }/ sadOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
3 ~$ U# V+ u# M- M' BadOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。- u; C4 w5 n& L
};/ u9 D( q: b( w2 R
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
+ u6 J7 X) R& G7 p. k3 [
. P2 k+ i" ~0 P) f! L0 A& ?enum LockTypeEnum
: @. H, C0 g4 M( r1 f# [{4 N- ?# Y* U% a; @, g8 z6 b
adLockUnspecified = -1,///未指定' S. g7 {, ^0 Y7 H, u3 ]
adLockReadOnly = 1,///只读记录集( i% N" F% A3 z! L
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
  m, \' h3 I  f* p% K. ^) badLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作; }8 z& l- C% O' S
adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
! M) j9 V# Q$ U& r- |}; . W2 e' @, D1 Q8 e

2 \; Z' J2 E# w$ f⑤Options可以取如下值之一:8 m! h# k7 G* E$ o3 \3 z* _
adCmdText:表明CommandText是文本命令
; X0 W* f, j: ]1 dadCmdTable:表明CommandText是一个表名" ?# H" H  U* j/ j2 k
adCmdProc:表明CommandText是一个存储过程' i9 c, E% [1 m  b0 |! @
adCmdUnknown:未知
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
如果我没给你翅膀,你要学会用理想去飞翔!!!
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-6-3 12:19 , Processed in 0.473734 second(s), 52 queries .

回顶部