QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集" Q% I% x2 }( _+ m% {+ @3 U
- h4 |/ b/ M' U0 G# o
  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
' j+ ~0 A  e! S& j. W2 C4 a: T! A/ H并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
$ i8 J  m$ M# C# X2 d* k: v+ xSQL命令的执行可以采用多种形式,下面我们一进行阐述。
2 I5 J) t* V( J" v* i
( I4 x! }5 J% X  (1)利用Connection对象的Execute方法执行SQL命令
. d+ y8 J. W! m/ d4 ]% L( O# n* g8 U  X7 M. N+ g( w9 b3 E& K- \, {
  Execute方法的原型如下所示:
( S2 ~, Y% b  E3 ^. \0 P$ w. D: T
0 a+ ^2 ^1 P6 C% O_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
& i0 q  n( k  j/ }/ N; C+ d4 v! x0 \- Q& f
其中CommandText是命令字串,通常是SQL命令。
9 u; W: V' G' B, a. D6 a# R& W参数RecordsAffected是操作完成后所影响的行数, ( l4 ~0 e* L- e. g& M) Z) o) T
参数Options表示CommandText中内容的类型,Options可以取如下值之一:
: a% y1 _+ w1 r& n# [* d- Y. C; EadCmdText:表明CommandText是文本命令. S, {; l* U" v* D; S
adCmdTable:表明CommandText是一个表名
) g; a% i0 j. o# U  ^1 sadCmdProc:表明CommandText是一个存储过程
! V; I1 Z. q7 z! }6 ]) C! O+ dadCmdUnknown:未知5 b! |$ b0 q' T8 g" [8 m
9 o  x* I1 h* d5 U& p, y9 u" X
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。 3 Y7 p' l7 w, a" F: U9 G
_variant_t RecordsAffected;4 g* W; h( U! m7 ~
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
) h( W4 ^$ h$ w( |: U2 tm_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",/ d8 u3 A! x3 S+ l  Q$ `3 m$ @
&RecordsAffected,
( I" K) l0 {9 YadCmdText);, a1 s! t3 F/ u6 ^: H
9 i* H) ~& Y3 f5 t0 K
///往表格里面添加记录/ P1 V8 A% n' K  I0 P" [
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
# `) y; U4 S" B3 P& o3 f9 X9 h7 I3 C- g% {  {& p; g& E' e
///将所有记录old字段的值加一
# I0 x6 s5 e( h0 f8 Om_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);9 U/ E+ S  U* r) F- K
2 ?. m8 M3 E4 s# p
///执行SQL统计命令得到包含记录条数的记录集
$ Q6 E  X9 `, D, im_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
* }5 [- P. _9 p4 m2 Q_variant_t vIndex = (long)0;
! s) D0 w2 G* x" p, a+ t* I( w_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量8 ?% Z3 m  |+ R$ ]& W1 G! k
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));. Y' p! `! {  T* X8 H1 G+ w! i
m_pRecordset->Close();///关闭记录集1 W3 ?! f8 n. Y7 f
CString message;. J7 n8 \  c& @6 c
message.format("共有%d条记录",vCount.lVal);
; E$ @5 b  ~) N+ \& n( W/ rAfxMessageBox(message);///显示当前记录条数
. N( e6 P5 K! }9 X
9 U7 V. c5 I8 a: a2 r; z(2)利用Command对象来执行SQL命令
) Q: S0 Z' \  |. b
9 M. C5 h& M" ?8 m6 `_CommandPtr m_pCommand;
' Z7 ^7 H/ I6 j! {# t1 fm_pCommand.CreateInstance("ADODB.Command");
4 y5 }( |; R* H, S; y( W2 S_variant_t vNULL;
8 Q6 d! o! c5 q9 R2 q4 A$ nvNULL.vt = VT_ERROR;% l( k/ n$ r: J1 h( n
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
7 L3 e- ^+ z  _  b. k; X6 bm_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
: G2 m) x$ K8 c9 j; r! C8 i: ^% Om_pCommand->CommandText = "SELECT * FROM users";///命令字串
+ J6 _# R0 K$ ^4 b( k& S! dm_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
8 u. ?# b$ t; n4 Q. C, E
& _9 {1 }% q- W9 U* A8 U  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。 0 q. f1 l7 \4 B/ m
9 E% n2 Y$ V# y% z9 J8 [$ v/ \
  (3)直接用Recordset对象进行查询取得记录集& V% ?& M/ m' i! s- E

6 }0 B$ \  o/ e# h* i$ n' S  实例——   O. ~! k8 Y8 H
% y, U' C! g- L
void CGmsaDlg::OnDBSelect()
8 v9 A7 N4 v1 U* g{" y: U+ |- ~% s; [0 ?4 F/ Z
// TOD Add your control notification handler code here+ }6 D( I) ?# q
_RecordsetPtr Rs1; //定义Recordset对象
- |6 {' M* q% z_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串* y6 m; }' o7 \5 X
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句, C. h& \+ G4 u9 L* K
::CoInitialize(NULL); //初始化Rs1对象
$ s" r, C/ i+ {" D  X4 I/ n4 t2 VHRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
! X) l0 I) `( T% L# l+ o//省略对返回值hr的判断
1 X( G2 q' x- }/ A! _* }0 YRs1->Open( Source,0 a1 F+ V/ v  `4 n! Q5 @/ p
Connect,* c8 {0 x" {  _' v1 a
adOpenForwardOnly,
. ^" S% H- _% n& W3 A: }& Z. yadLockReadOnly,
( q/ ?# i; z8 A" X6 Y9 G-1 );
" W- Z5 F% s2 t/ X. ]' v3 W" F: T. |_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
* h1 \' y/ |, W; g% Y) |+ gCString strTemp=(char* )(_bstr_t)temp;
0 y& Z" B8 H7 Z" @. MMessageBox("OK!"+strTemp);
6 @2 h9 u8 z1 ?1 ]2 |8 `9 L}
0 E3 o8 d1 H2 F9 D; s
3 p7 [5 Q6 a5 |5 X3 {, ]例如
- w1 E! l$ {$ `0 C6 v! c% d: c; }* Em_pRecordset->Open("SELECT * FROM users",0 t; h9 }; d; N/ }/ ?
_variant_t((IDispatch *)m_pConnection,true),
5 A  a0 K( V% m' f1 Q! R! JadOpenStatic,+ f: O& z2 H' J7 X; F
adLockOptimistic,* O9 i1 o! g! f3 W) B/ S
adCmdText);" V3 C  n: G- Q9 z8 ^" Y( k

7 o4 [3 A) V+ s. E0 A8 SOpen方法的原型是这样的:8 ^) ?/ I, M8 [  H
HRESULT Recordset15::Open ( const _variant_t & Source,
$ R: X9 @' r; B, hconst _variant_t & ActiveConnection, 8 y/ n) i8 O; b( |' Y+ A1 C2 `
enum CursorTypeEnum CursorType, 2 J9 @, f: J7 n. K8 R
enum LockTypeEnum LockType,
6 L0 r5 h0 a+ e6 x( Y) |long Options ) 5 ^% _  ~5 n7 S2 L3 E$ q6 Z

+ D1 |" y# S2 n7 ]3 p其中:: X( I, Z" h. S) O$ ]5 e5 n8 J  q( \
6 |* B0 P1 b' A8 t" I/ z
①Source是数据查询字符串9 p# T4 {6 Z2 U$ c2 ^- a
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象) 0 Z/ H( r7 f  Q6 o% b/ p& v, [+ J$ j
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:/ z2 u; m* L# g  [; V( ]2 }0 g
9 S: P/ O+ O1 Z! A4 g0 @+ M3 ]
enum CursorTypeEnum# w6 L! X+ ?- r: \0 t/ s" i5 S
{
6 ]$ q5 P4 T& P$ m! I$ i! ^: ZadOpenUnspecified = -1,///不作特别指定
  b/ ~5 h5 @5 sadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用$ L* ^  z$ x8 b3 J  q4 w' n  @2 W0 I
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
  m: u  G$ H2 k# B$ E* v# _; |- h  w9 }
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
. f  e4 C# [7 @% F4 A2 KadOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
& r; t0 l; l! n};: T  K; v, ?3 [; g- y7 ~
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
! _9 g+ |  M7 M" D' J9 U* l' k5 P$ a: f' ~
enum LockTypeEnum
! z6 D& l  B7 R- ?1 [" ~. P& E2 J+ d{5 J$ a9 w6 g/ y$ y7 v% u9 V; ?  e
adLockUnspecified = -1,///未指定
+ K& S; o, ~% d8 E( V' Z0 r* [adLockReadOnly = 1,///只读记录集
4 s+ s4 |# `! j( V1 MadLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制$ }+ \$ {# v. \+ ~, T* Y+ S
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作5 Y  f# u7 M: \) ]
adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
5 C4 M8 r7 C, j3 P};
# n  ?: M6 S; T& I$ e) C* |. y8 A5 g& y+ g
⑤Options可以取如下值之一:
/ \) L8 e# Q; `0 q& {4 a) G* qadCmdText:表明CommandText是文本命令
- U" d) U5 u+ Z5 LadCmdTable:表明CommandText是一个表名
+ U1 Q1 n% P9 _6 p" N9 k* C& N2 nadCmdProc:表明CommandText是一个存储过程
5 ?. x' v+ P. p4 eadCmdUnknown:未知
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 10:33 , Processed in 0.481244 second(s), 52 queries .

回顶部