QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |正序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集
! V* ]) A- |' y7 j0 m( C# Y, E4 f) x' L
  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;- j: a) a7 I3 @4 v
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");' |+ a+ x3 O7 z: A) x3 e5 c
SQL命令的执行可以采用多种形式,下面我们一进行阐述。
- t. c' T8 f: F. d+ `5 R% o6 k) i9 J: z8 `9 S; k4 B
  (1)利用Connection对象的Execute方法执行SQL命令$ z4 E0 n( w6 s5 S
1 ?3 V% z/ R0 F
  Execute方法的原型如下所示:
, G3 f+ r5 g* q6 Q. J1 J& |% z1 o4 e: H
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
5 R6 y) l& a2 z2 ~
( l* l! ?) L4 a$ z- d  {! ]: B其中CommandText是命令字串,通常是SQL命令。! P  r* j2 x) g2 J) M
参数RecordsAffected是操作完成后所影响的行数,
. F& u0 o0 c" n% }5 O参数Options表示CommandText中内容的类型,Options可以取如下值之一:+ ?" g. c( {6 }% I$ Z# r* e
adCmdText:表明CommandText是文本命令
7 b% F( ]5 l  f* `+ VadCmdTable:表明CommandText是一个表名
- }: k$ I0 J6 u6 ]9 IadCmdProc:表明CommandText是一个存储过程, b  i0 E7 ], M" B  x9 h
adCmdUnknown:未知  T4 F9 F* X) M" P% D
1 G, w1 m4 E( k- k: ~, {
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
8 I% V( \7 ]0 \. F) O_variant_t RecordsAffected;
; C/ g! M) ~" M1 n2 {. t///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
5 z/ o5 z! K: G. W: b, [/ {' `& ]; @m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
" B4 v- T0 s8 Z/ x&RecordsAffected,
. V. g4 L; F2 X! D, N, E+ J8 ]adCmdText);
6 X% h( q: ~4 p5 C( S8 ~" _3 A. e( f! X
" b3 ]+ ^/ s' R, h///往表格里面添加记录
2 T, ]# y! a8 z/ Q+ e1 j& `; um_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);1 U; R9 ]4 ?; n4 S0 J7 B
, u, ^4 @0 c/ v) a5 y
///将所有记录old字段的值加一
9 Z# q* Z8 G0 R* a& c% b/ Wm_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);, t2 ?9 b- y7 x- s
6 S' ]2 S) L7 G" W1 M
///执行SQL统计命令得到包含记录条数的记录集
5 [2 I$ Z0 K$ Qm_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
* k! Z' v1 D7 |& o) n% f_variant_t vIndex = (long)0;, @9 U$ j/ J; F) U1 L# V. r( ^
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量4 ~6 @9 H( H& S9 W
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
/ Y6 H& @% W6 e; m7 Z2 x" |9 g1 p7 ?m_pRecordset->Close();///关闭记录集0 Y, L: J2 G( n
CString message;
' b2 o) Z0 o1 Y( f9 d3 Umessage.format("共有%d条记录",vCount.lVal);
% a9 w9 z0 ]4 N2 |4 r6 r/ NAfxMessageBox(message);///显示当前记录条数8 G- D. ^" x! f3 ^
" w. F0 z0 m% B7 |( Q# ]
(2)利用Command对象来执行SQL命令
: `2 E" d% Q8 i) @5 o9 u& |; G) V! o0 M8 `" I' ~" [8 F6 l
_CommandPtr m_pCommand;6 y1 o' p. ^' Z4 Z6 l5 B% a
m_pCommand.CreateInstance("ADODB.Command");& \7 m; l. c& x2 J
_variant_t vNULL;6 r* c5 s- t6 n1 f# i
vNULL.vt = VT_ERROR;
7 q5 x! k  z' Y+ x+ P3 rvNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数6 P' ^( V" C5 Q
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它$ v* ?- N/ K; @
m_pCommand->CommandText = "SELECT * FROM users";///命令字串
& o+ I* K" s6 S9 S1 F; I' S6 ^8 p: am_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集) e/ r/ j  Q, J1 w. y% k
7 l$ b& |! D5 s% x! U' ^
  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
( A5 t" B$ ~9 O  r5 I8 Y
4 z! J) y8 x2 a; c1 C& Z( w7 {  (3)直接用Recordset对象进行查询取得记录集+ b1 c8 V4 w3 F; u

" x4 V3 P2 j& {& y9 A  实例—— ) u* y5 n2 A' D3 s
7 b5 @* c% g! U& q) L' z5 G% U5 B
void CGmsaDlg::OnDBSelect() ; l/ e0 p( j+ y- U
{
* N1 X7 f" [0 w+ y8 ]. s* i// TOD Add your control notification handler code here+ J) e/ M9 F" T- m
_RecordsetPtr Rs1; //定义Recordset对象* p, n/ E0 M" s6 B: Z& J
_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串% [% a! K% K/ X4 f" I& l+ j  `
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句6 E: M. v) D, f* ]
::CoInitialize(NULL); //初始化Rs1对象
' E, S3 w+ a$ A4 L8 jHRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );' U: c! a- H- y& `% P" N" C
//省略对返回值hr的判断
6 [8 Y1 ~3 I  A$ D9 DRs1->Open( Source,. C: w( T  v. ?/ r- n7 b
Connect,, }& N9 ?! C; p7 @
adOpenForwardOnly,) q+ d# h9 o/ \5 v0 V2 m) P; b0 n
adLockReadOnly,& K! r% J) x$ E# ?3 j
-1 );
9 g; ^# v- G, U1 T/ a_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
/ k+ R* w& b" A$ _9 @/ cCString strTemp=(char* )(_bstr_t)temp;
6 ]+ @9 C+ N0 {9 ?; O- y( }MessageBox("OK!"+strTemp);: c# [; T2 w  U3 [5 C9 C/ D
}
% f. q6 o6 X- r( j' g8 Z
+ z7 r5 w  u# w+ F2 s' h* Q例如
" _8 X- ~  d' L) p% C( a. Im_pRecordset->Open("SELECT * FROM users",
! F( V" ~2 R; @; b) T4 P& l! @_variant_t((IDispatch *)m_pConnection,true),
' z& e, g# c' H6 X; m' zadOpenStatic,
# X9 w8 b4 o/ @adLockOptimistic,; [' G, E" W3 S1 b8 \7 ?  i; Q
adCmdText);
. l9 A+ a8 `$ v3 V+ h2 B5 G# Q0 }" P9 B6 r6 S; N
Open方法的原型是这样的:
1 \0 E9 Z2 K% d* @3 cHRESULT Recordset15::Open ( const _variant_t & Source, 5 h1 ^6 J; _- Q3 G4 Z. v
const _variant_t & ActiveConnection, : x7 h' q0 i! }9 M  L) [  M
enum CursorTypeEnum CursorType, 8 V4 `: V* D8 ~) n! t5 r
enum LockTypeEnum LockType,
) h+ J/ ?% M0 C! s2 G: Clong Options ) + X+ S# t* u! i* Z/ z+ m9 |
5 e! S/ u" ~% w% c! G+ D7 l
其中:
- }0 Y- p- a" l  _
# p" S0 L# v' H) w9 M* |①Source是数据查询字符串% E0 v2 ]; v/ Z2 w, ~( u
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
1 x6 k; h2 j, Z" V+ n: W③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
$ {( Q. i0 d# ~* O# x, d- h
  P/ v$ `7 G% l& aenum CursorTypeEnum# ]9 A4 L7 [# ?9 U( y3 C, X
{
3 l4 P: Z4 J; B: v+ P* p& fadOpenUnspecified = -1,///不作特别指定
* n  `2 ^9 ]: wadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用' F! ^7 ^5 T3 J- {: l! }
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
) c3 E! `) A+ T6 Z: N; O+ e, I# F# a- j0 ]( H& N; `) L
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。. y, T4 d$ [( R; [2 R/ T
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。' O* y! _+ |/ p2 Y
};+ _1 y+ b4 _! _0 a7 z9 x
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:) _; c! A/ a7 h4 X: L! ?
0 P8 k* P4 G& d8 h2 E; N* j
enum LockTypeEnum3 ~, x5 I, w' K6 r; `
{0 M/ K& r5 W1 I7 O! `7 a; v" ?% F
adLockUnspecified = -1,///未指定
# S5 z; f: w2 j+ Q) cadLockReadOnly = 1,///只读记录集8 i" @! x5 M, f' p
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
1 |; b  |' q2 k! ^9 L, CadLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
' l; W0 n9 F+ _" Q' g2 \. y9 a. \adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。; ^5 C% j! [* j( \
};
, L: P$ ?1 |7 l7 f: T2 Y& K  {% W, A% s( |. P7 E  ^/ j: m4 B
⑤Options可以取如下值之一:
- r- b+ [* e2 Y6 a5 gadCmdText:表明CommandText是文本命令; [, ~$ `/ ]2 X8 `
adCmdTable:表明CommandText是一个表名3 p4 A7 Z7 Z, [/ a& P# y  f1 K
adCmdProc:表明CommandText是一个存储过程
' Y0 v5 d4 ~5 ?* uadCmdUnknown:未知
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-7-19 16:00 , Processed in 0.405914 second(s), 53 queries .

回顶部