QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集
  Z) U) l+ P+ j+ [& h3 q8 z7 ]
) W0 ?3 l; n. x, \  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;; e0 w0 ~. ]  a5 B! c4 i
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");: N. g3 @/ g2 C' n- k3 [
SQL命令的执行可以采用多种形式,下面我们一进行阐述。9 W+ f  m1 s5 S3 ]/ c; q

. z( p5 ~6 F( s: T4 q. P  (1)利用Connection对象的Execute方法执行SQL命令0 N5 M$ ]! D4 _/ P

0 x" }) k; G; G  Execute方法的原型如下所示:- Z! T2 I% B5 ~- d- r

! [- h3 U$ {7 |4 M$ H8 l: ?4 X9 j_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
- g( K$ [' n% M2 h* W! T
  g0 i: A, A' g3 ^: ^其中CommandText是命令字串,通常是SQL命令。9 B% s8 l- `! I! x$ Q
参数RecordsAffected是操作完成后所影响的行数, 4 f# X3 ], Z' m) Y2 q' q) x+ ^
参数Options表示CommandText中内容的类型,Options可以取如下值之一:
# C6 J2 N3 ^" R+ l; Q, U( v; NadCmdText:表明CommandText是文本命令
' K: v8 ?/ I7 }1 r1 ladCmdTable:表明CommandText是一个表名
5 O" Q- |, Z& N; @, _! R$ R) SadCmdProc:表明CommandText是一个存储过程
7 }8 a- C, ]3 }* |. YadCmdUnknown:未知* Q, o( I) k  b! b4 k5 k: V, f/ x7 n
, ~( x; Q3 ]( v  Z8 o2 E7 l; V
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
, k# _) |3 a: B8 W- ]% C' M5 m_variant_t RecordsAffected;4 s3 I9 D' y! N/ l1 T2 h/ N; t( _
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday& s  R3 m2 n( j* E6 J
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",& D7 H9 J7 u3 @5 ]
&RecordsAffected,
4 Q- e: W- i7 x: F* `0 Z, S1 M5 f5 J/ FadCmdText);
1 W5 ]- r& y. K2 t2 k' v0 \
, k& Q& g- {6 F$ U3 R$ r' P///往表格里面添加记录
  e# `3 B; p" Q' U, G( L9 Gm_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);& W' a$ ~7 w- D! E/ |. Z# M, T

1 ^4 i* H& s! T5 W///将所有记录old字段的值加一! M  S& ]# I2 Y+ ~# E3 g" E
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
/ ]$ a& ^* k# E
0 T- j9 m/ X4 o5 f& E, r. j( N///执行SQL统计命令得到包含记录条数的记录集3 M' [0 ?$ L9 l8 z
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);0 U8 E- c$ F" B# J* }% c
_variant_t vIndex = (long)0;( h: K: h; }! D+ n
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量: Z3 K5 e7 v0 \, r1 @8 W7 u
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
8 H9 _  F( k, a; x" t* X6 Hm_pRecordset->Close();///关闭记录集
& T1 e% q) l8 m# {0 W( @3 `CString message;
+ n/ `9 N- f/ Xmessage.format("共有%d条记录",vCount.lVal);6 x3 ]& v0 T% J7 x/ |. P
AfxMessageBox(message);///显示当前记录条数
+ o- s+ p& A( g' I6 a: l, e2 I* y
. r' W+ h  D# n( q% y, ]8 `, \(2)利用Command对象来执行SQL命令 ( U9 b: S1 y* ^* z' x
- u' V# \7 g1 w  K" c
_CommandPtr m_pCommand;, Z$ m: T/ F# ~0 Q) N: v
m_pCommand.CreateInstance("ADODB.Command");5 E, m  ~: O9 j2 j& B
_variant_t vNULL;
. r& D0 r7 L0 v+ ~, rvNULL.vt = VT_ERROR;
# y6 E8 Z7 S4 \- p- AvNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数: R% v) {, i7 j9 c  _! q0 u! \
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
* I7 W8 K0 h. L. b. zm_pCommand->CommandText = "SELECT * FROM users";///命令字串
" l' U/ `* j7 P' |m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集- N, X9 f/ j# K% N8 M  [3 w; X4 Y
  W4 m3 p0 _4 f" L' f& `
  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。 5 J. z$ }: h1 G% v4 O4 m! \' {
: @7 T; n2 G# w0 b
  (3)直接用Recordset对象进行查询取得记录集7 e0 y( ^; ?( q8 q9 {

1 V& d7 l3 q9 Q  实例——
1 g0 d6 D/ v9 v% A1 V4 }' X( B) p
void CGmsaDlg::OnDBSelect()
) F+ D  f% o  v2 u7 J  N3 f{7 I# q4 F* k' D  v  [# `
// TOD Add your control notification handler code here
( r9 c# Z# C) e" e( P_RecordsetPtr Rs1; //定义Recordset对象
/ A" i) W$ D9 Z2 b1 w  n2 r_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串$ |" t- O! e0 k' ^
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
! G/ F  X! C* o3 Y; m::CoInitialize(NULL); //初始化Rs1对象- v) @+ a+ p0 e+ y' r1 [7 ^
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );: J  g0 Y' K& L  ^# z
//省略对返回值hr的判断
+ |8 b! f3 ^. m0 I( ]  L9 iRs1->Open( Source,3 q9 j! G; \7 M+ H! ?7 ^
Connect,
, ?7 S6 o% U- l) u& BadOpenForwardOnly,
0 C) j8 \+ G; @* badLockReadOnly,
; x; j& W" ?( y( @' |  f-1 );
) s& e9 g2 ^# l0 {_variant_t temp=Rs1->GetCollect(_variant_t((long)0));( g4 [4 `, s! h) T! O5 ~  E5 J  d: Z# z
CString strTemp=(char* )(_bstr_t)temp;1 E. e# S0 @9 _4 B! p
MessageBox("OK!"+strTemp);5 x0 S, [. H# y0 H! P& X3 h; c
}6 ?! O+ \. Z+ a! d' n
- l9 H% }& w, r( V
例如
: E# E  z  I2 ~6 z$ N# R& sm_pRecordset->Open("SELECT * FROM users",: U  y1 J/ _6 o) a- x
_variant_t((IDispatch *)m_pConnection,true),
9 U% P- X9 {% o$ ladOpenStatic,
' Z1 |& S4 g4 J. z/ ^! `8 `/ |1 f# xadLockOptimistic,$ |  y' j$ \& F  ?$ I
adCmdText);( D, N& G5 Y3 a' G# o. o

( [( i3 P$ a4 W2 I3 C* c# rOpen方法的原型是这样的:
  `# [& E: g0 wHRESULT Recordset15::Open ( const _variant_t & Source, ! m9 v) {. B4 s& V7 _% C. B* `
const _variant_t & ActiveConnection,
2 |% d+ N6 O2 i: Wenum CursorTypeEnum CursorType,
3 h; P) A4 W0 e4 X* Ienum LockTypeEnum LockType, 3 \& c+ O1 V% A8 l+ H, M
long Options ) * a* s' `0 b2 S. Y

! G3 J" @. C! ]+ S其中:, K% y+ V& t/ \+ ~

/ l# _8 V$ T5 l( n, d7 D①Source是数据查询字符串) G) p# _" y+ l, @  o0 e
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象) 2 h% Q/ ?2 ?! B, e
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:7 X/ N5 E8 h" J  R1 ?

! U/ T& P/ C: o3 H6 d% P2 p3 Eenum CursorTypeEnum6 `. D+ ~. H+ i2 g' R  T5 d1 }
{
: g) ]- P: C% B# sadOpenUnspecified = -1,///不作特别指定( d6 g5 l& F, S# |4 v
adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用% l8 h  f4 i8 x" j  Y( J
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
7 n* y6 ?! H3 G2 f: o2 u0 v. G
$ W  S2 k8 S- w# I) D, }$ z7 oadOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。( G2 R0 V7 Y/ H8 J, [/ C
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
5 w, d; A% ?% H$ x' Y};
1 P) ]& S9 Y. F  P& u④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:8 i# V1 V- k! I+ w( ]7 h
5 z1 B/ d% F, W- f& h
enum LockTypeEnum
& @' g. N# H* m{
# P# T+ e6 |9 J1 YadLockUnspecified = -1,///未指定
* B( L  ?0 ?: J+ F! LadLockReadOnly = 1,///只读记录集
) E6 a; ?+ B+ ladLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制# i0 F+ H: |/ q2 L: Y* e6 R3 p
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
6 \; c- o8 k* madLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。5 L3 `# W  a% l, ]
};
# {1 N  t/ @3 M; P# f
5 o! E2 I5 b( y+ z) m, c; s7 m' p⑤Options可以取如下值之一:
' L* n9 T$ c6 @) {1 FadCmdText:表明CommandText是文本命令
' l4 P# R3 D& I7 {6 dadCmdTable:表明CommandText是一个表名) U! p7 f+ T' e; L/ H' g$ ]
adCmdProc:表明CommandText是一个存储过程( b5 K: w3 i3 b* x4 z+ ?
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-9-3 22:29 , Processed in 0.367984 second(s), 52 queries .

回顶部