QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集
$ V3 u3 j" `7 G% |- p$ b$ }' }' G) d0 h# P* y% c
  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;3 P, K8 s0 S4 F$ `; e- z
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");% W) ?5 w) n# ?
SQL命令的执行可以采用多种形式,下面我们一进行阐述。
+ X# z8 O. H' D- Z9 r8 G' e7 ~; v4 `* H& n
  (1)利用Connection对象的Execute方法执行SQL命令' E; m+ ]9 p# Q2 s, x; \

5 X: v1 o# A/ \2 W6 {2 z% [. Z$ W4 d/ ~$ ^  Execute方法的原型如下所示:8 k- w$ \9 K& R- j2 c( v

) I% M% H2 ?5 m' t8 a_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) 7 o+ _& Y1 w/ H$ T; I1 Z

. m; X) u: V4 s* i7 p: R# v其中CommandText是命令字串,通常是SQL命令。
. B7 ~3 W1 G! j( `, V参数RecordsAffected是操作完成后所影响的行数, $ I/ m8 ?) |' {7 \$ ?
参数Options表示CommandText中内容的类型,Options可以取如下值之一:
8 v4 \; a* `; IadCmdText:表明CommandText是文本命令
4 }& z8 Y6 i. S. s: v) V, DadCmdTable:表明CommandText是一个表名  w% o, Z, l: |% W1 s
adCmdProc:表明CommandText是一个存储过程
/ M+ n3 u; f" @! jadCmdUnknown:未知/ m  e2 \; l0 d  M# `% _
& q" E5 H. F" b0 \! `) m
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
- S2 q" y5 q- k/ I* t_variant_t RecordsAffected;9 n8 ]- Y" d6 ]( C( Y
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
% \- ?+ K* ~* i5 x3 T3 B$ [m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",, |+ \2 x6 n* F
&RecordsAffected,) o% n  Q  B5 I" f
adCmdText);
5 G7 k  E4 m- V% _  H" E. J
" R0 `  w5 ~" h///往表格里面添加记录
9 i6 P; W1 b2 K6 ^5 x: G% o6 Dm_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);' O  f0 }; L& f# e- f' P" ^
( v( X8 u+ p; d
///将所有记录old字段的值加一
1 s: _# h( v# ^  Lm_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);0 {& [. n2 M  E: P' v
) _8 h1 S* B" E  V
///执行SQL统计命令得到包含记录条数的记录集: J! s) J+ |3 w6 U
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);3 M- W$ _9 [) ~/ O1 f+ c( r' e
_variant_t vIndex = (long)0;
' l! O; y( P- _% L0 B( j0 h_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量7 Z6 k- s6 v: [8 }. b1 r& J8 p
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
$ R, k, |' m, U; a' z+ Jm_pRecordset->Close();///关闭记录集
& f7 C* C6 g0 cCString message;
' X# |) a# ?' i7 Tmessage.format("共有%d条记录",vCount.lVal);$ v. D" V% h. P: ~8 z- }
AfxMessageBox(message);///显示当前记录条数
7 X2 h; g( c+ A6 b2 n) U; M/ T2 R! G: I- s; O+ ]
(2)利用Command对象来执行SQL命令
# o7 L3 N) Z3 u  A; u# r1 A; I  ]5 D  F# I* v% _
_CommandPtr m_pCommand;( r. |! A1 H7 c) a
m_pCommand.CreateInstance("ADODB.Command");; X  |: c, r& ~" X, C8 F
_variant_t vNULL;+ n3 q( c* n! H* L' z( F
vNULL.vt = VT_ERROR;
7 ~6 D  p# [6 F4 rvNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数, R" Z4 n! o: u3 ~' A2 V2 o
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它- k$ I( I8 H$ S2 m& R
m_pCommand->CommandText = "SELECT * FROM users";///命令字串
" C. }; n+ o2 q/ e9 N% v$ ]. ^. Om_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集1 M3 X- M- N4 i% n+ T+ t" E
' _" `8 p' s) K' ~; B
  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
! W% g, c" N! I: l8 h% N% O3 m1 n7 G9 y8 h
  (3)直接用Recordset对象进行查询取得记录集6 Q5 H, W+ Q9 P: F* O5 h, x

9 I2 a: c/ Q/ b3 X" i1 k  实例—— 5 u& @) j; j! [9 [
- K! d2 A, f0 H2 h( E) ?$ V) A
void CGmsaDlg::OnDBSelect()
3 F# e3 c, O8 b{
" |4 M; W7 ~5 j* E// TOD Add your control notification handler code here
1 \* [2 I7 m6 h* ?6 ~6 O_RecordsetPtr Rs1; //定义Recordset对象* D1 R, o# I2 D; s3 q( L! c
_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串
: R- i7 Q  Y0 d4 @1 @_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
7 q& {, o& ~) C' [7 {::CoInitialize(NULL); //初始化Rs1对象) k# i) k& M8 e$ [" y8 p( x
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );2 {  Y( Z; o! |
//省略对返回值hr的判断 ) `2 n9 }; E% {& x) L$ Y6 N7 o
Rs1->Open( Source,) [" A+ I. ^$ L* e3 _0 u4 `( m3 R+ E
Connect,
1 p0 Y5 ]% F8 y- J8 G3 l1 vadOpenForwardOnly,+ s( c  M( e" N( D( H
adLockReadOnly,: Y7 |! L( T. K3 }. D. C( j
-1 );
8 P8 s- }& e2 A* d$ E2 T_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
$ ~* N9 O+ W9 f5 cCString strTemp=(char* )(_bstr_t)temp;
! y7 n/ h( {/ g1 e9 \MessageBox("OK!"+strTemp);
/ d6 N8 m$ s2 M}
9 ~% r( c& R  m" W6 R
4 H% y! \# D( a7 V例如 + I. j% u, \, T8 T# @; f
m_pRecordset->Open("SELECT * FROM users",
. m1 M3 X2 t' }( M3 W_variant_t((IDispatch *)m_pConnection,true),
6 U# e5 _" Q1 ?7 g: m; UadOpenStatic,& G! W) x2 c: m7 b2 m' E
adLockOptimistic,
/ v3 j( h6 Z" f# j' OadCmdText);
( _; f5 H! s, x  X+ d
3 t+ b9 F6 C7 E* W( e+ g5 a1 V8 |Open方法的原型是这样的:
2 O3 p0 \3 T$ N  k" X1 l7 j% x+ FHRESULT Recordset15::Open ( const _variant_t & Source,
0 C$ i) c% M6 ]const _variant_t & ActiveConnection,
: N2 a4 L. z" t, i/ zenum CursorTypeEnum CursorType, 4 H0 o1 ]8 `. A* m" P: }( |5 t
enum LockTypeEnum LockType, 6 x% @" q3 h7 i* t
long Options ) $ N2 [7 {. A+ y4 H; K1 l0 v

  q& s2 J# t3 M, I+ q1 Y2 m/ g其中:3 E6 j: A7 Q( n5 y# h

0 y6 ?! l, u) ]- ?0 q①Source是数据查询字符串
  o8 {! O3 i# Q4 y3 q②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象) * X6 ^# _/ L) z4 }0 g# }
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
3 z! W0 }5 T3 z, R
" ^7 W* V: U* ~4 menum CursorTypeEnum# R& Z; Q0 m( K5 V3 X. j
{
4 c% i% w1 k% oadOpenUnspecified = -1,///不作特别指定
' x# _- m9 E/ o6 m- ]adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用/ r8 o. j8 y0 @# ^  u
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。6 E. @5 U3 \1 Q" ?

8 W$ a4 n2 F: C. JadOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。" g& i& X' J. a% E  e
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。% t/ g" }4 W1 ?& V
};
9 j6 l+ q1 B( `( n. r$ P0 ]④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
/ y0 ?, P1 M7 t! M4 F5 w3 J' q
1 p: [6 P5 u/ X% yenum LockTypeEnum
+ C- g% P: ]. ]" |7 F! M5 m1 \{
8 L& J, }5 ]! E9 u: E+ N  U/ r$ _/ C7 WadLockUnspecified = -1,///未指定
* }# a1 D6 c8 H6 O+ aadLockReadOnly = 1,///只读记录集, O$ `% U6 z+ b" C% i3 c" m2 D
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
1 F: ]; d+ Q1 a8 T9 ?  F1 gadLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
8 n& o6 u1 }* M: ~4 ^) ]adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
8 i" D8 Z# i  a& {};   i, @+ T& d& \: K! m
) Z2 v: {3 }8 ]$ |& R8 ~3 [
⑤Options可以取如下值之一:
+ }% O# _' x" ~4 s8 ]1 z, @* ~adCmdText:表明CommandText是文本命令
8 @1 P6 |" U  ^; S( Z5 {! hadCmdTable:表明CommandText是一个表名* i6 g2 L' b& J. D( m
adCmdProc:表明CommandText是一个存储过程
/ M* f1 y! E" I1 G$ YadCmdUnknown:未知
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-4-18 17:14 , Processed in 0.518007 second(s), 52 queries .

回顶部