QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集
& i" D1 q  R" q' ]# y( i3 B- i! v/ t7 H3 S8 b8 K0 i: P7 c
  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;3 z( d5 Y' d7 O4 H
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
% z& m! U+ \' @, b) \5 [SQL命令的执行可以采用多种形式,下面我们一进行阐述。# y2 B$ D1 Z0 G2 ]2 r

4 `5 r! V6 B/ m* O5 j* v8 o  (1)利用Connection对象的Execute方法执行SQL命令; Y& c( D  h# v. f& z. I
2 R" W8 p/ y7 [* {% Z2 R" v
  Execute方法的原型如下所示:5 v2 o" X0 I7 r2 A2 l; `$ j+ ~9 z  c
5 ~3 @  e: _0 ~
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) ! K/ P( P* w2 t/ B# q

+ |' Q& t& ]$ c, l其中CommandText是命令字串,通常是SQL命令。
% [* E8 G. {0 c3 G7 X' G1 ?参数RecordsAffected是操作完成后所影响的行数, 0 X! b4 l+ j0 R- s, M9 A
参数Options表示CommandText中内容的类型,Options可以取如下值之一:0 t3 N/ [1 D- ]
adCmdText:表明CommandText是文本命令8 I( \, L% }  Z& g* e8 I* D
adCmdTable:表明CommandText是一个表名
8 j0 F- v0 I; wadCmdProc:表明CommandText是一个存储过程
$ E! p# L( n6 {; J. i- ZadCmdUnknown:未知: _! a% V/ {4 ?0 W

& e5 k6 `+ w9 p) h0 v4 rExecute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。 ) l0 B) g9 `5 p) e
_variant_t RecordsAffected;
( Q7 X* e9 o$ x  v: \0 S$ o" |///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday' j- |. f% S$ v! D
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
( Y9 p4 S$ P3 H% y  i0 t  r! M&RecordsAffected,
4 @, e7 a- s- n: ]2 _  |adCmdText);
; U& V' F/ I6 D' O" k8 H9 V
$ d" s! y. v( F. _: P6 W: z/ N///往表格里面添加记录$ V  G! g4 J% c/ \$ r+ t4 l2 q4 _, ^
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);; J2 J6 x, h/ U- f- g+ i- B1 r

7 c8 b- P' U8 B' B, e///将所有记录old字段的值加一3 k0 ]) v$ J7 w6 g
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);6 E" u/ {, `+ r

" A) M9 P4 }4 C( l///执行SQL统计命令得到包含记录条数的记录集  H' c( I& `" T0 @" H  {
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);6 B! i* b/ L. b7 O; g. e7 R( ?, y
_variant_t vIndex = (long)0;
( K* z& m/ I! c# D$ E8 ?$ d_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量) K$ j% _" P# s
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
  T- q8 v. f- N; e  P( I) gm_pRecordset->Close();///关闭记录集3 c) S' K7 V; ?: e6 [. o
CString message;
7 Q: P; T  C. _, a; T3 w8 b! ]message.format("共有%d条记录",vCount.lVal);0 O' {; P6 P, L! x3 ?( A; |' }3 o
AfxMessageBox(message);///显示当前记录条数
0 S. u8 b" j  s  Y! e0 R! m! H% w. A" A/ }7 R1 ?5 B2 U
(2)利用Command对象来执行SQL命令
9 R, t; q, }+ K7 _
- g( I- E2 N! f# J_CommandPtr m_pCommand;4 m- W1 w& j5 p1 S. M
m_pCommand.CreateInstance("ADODB.Command");$ P/ `3 X+ \( T
_variant_t vNULL;
1 M* H$ E" P8 yvNULL.vt = VT_ERROR;
+ e# p3 \' }/ v! pvNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数4 z. i/ f! K5 U- w: n
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它+ G4 {* ?/ J5 a/ ^! x& g  C, z
m_pCommand->CommandText = "SELECT * FROM users";///命令字串6 i4 `8 i1 k  Z4 q  W: V
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
! Q: Z; {. y% q6 ]5 c' q& p' B8 T$ E2 M9 b0 ]
  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
6 T. p: e) H! T$ C- p8 ?# e, O4 f* g2 g
  (3)直接用Recordset对象进行查询取得记录集
8 l. W9 }, V! h4 s$ M2 i; l  p" a- M% G* p3 r5 P0 ?5 C
  实例——
. h, z  Q5 t0 M0 \" ?3 Z1 R
, H4 E, V; k& Y* x( C# j& K& Ivoid CGmsaDlg::OnDBSelect() 7 c3 v' c3 r. H$ I9 X& I
{
' k1 k$ M3 X& l+ z9 h! y! q1 q// TOD Add your control notification handler code here
; k0 |8 \& o8 C+ v: y$ |( T_RecordsetPtr Rs1; //定义Recordset对象" p; s0 y9 y$ s: u2 i
_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串! t& t+ [6 [3 T1 D! l
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句+ }, H/ j6 j: t5 ?6 a( F
::CoInitialize(NULL); //初始化Rs1对象
: W* Q# `/ h. O! j0 M, pHRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );& y% u, x6 y$ P( @
//省略对返回值hr的判断
! q' v) [( B& I, {; A6 k: QRs1->Open( Source,, M, q/ x6 o8 l. ^5 D  D- ~" s" N
Connect,  e5 y5 W, t" R# C1 Y. W9 l
adOpenForwardOnly,
- n& l& G9 N& {1 P( ?adLockReadOnly,) `$ j* V+ M# L6 d) {7 _
-1 );
8 l) s: M/ Z6 ]9 c( ^_variant_t temp=Rs1->GetCollect(_variant_t((long)0));7 X9 H7 c6 z' V3 c
CString strTemp=(char* )(_bstr_t)temp;$ h# @( m9 O/ [2 U, x. N
MessageBox("OK!"+strTemp);2 u/ D0 a9 h2 |
}
) ~' s3 M( q: z1 t7 ~/ ]5 u* r: \! d4 H
例如
4 y8 ~( D% i1 N7 dm_pRecordset->Open("SELECT * FROM users",# H/ L7 H# ^0 c# U
_variant_t((IDispatch *)m_pConnection,true),8 ?( r% g$ _( ]* u
adOpenStatic,
+ T$ o% a# [& }# ladLockOptimistic,0 ?5 P3 }4 p3 c4 r; e: Y4 \' z- {/ k
adCmdText);8 ]& g3 e/ k/ c" J6 T- p6 S2 c; l
$ v$ X3 B" z+ e" y
Open方法的原型是这样的:+ ^" m: M1 `9 x8 Q* W; i
HRESULT Recordset15::Open ( const _variant_t & Source,
; D( f1 L: q: ?. F: j0 e% lconst _variant_t & ActiveConnection, 4 S5 e3 \7 p4 q) K: j
enum CursorTypeEnum CursorType, " u* ^6 v+ R0 W  ~# l) _
enum LockTypeEnum LockType, 6 b4 ^9 Z7 |+ B
long Options ) 8 b/ M- H$ `* V( x  i8 b. G7 r" j. {
  F& M0 y% q, X" R: n2 q
其中:
; n! i7 |+ R  q
3 r; r$ d* x- j; d- A. o0 i) ^①Source是数据查询字符串
: J! e5 }. f: d% x$ I②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象) ) K1 w' ^9 u3 l/ |$ J+ n
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
6 g( q& m" j. O  r5 ^( R2 M% ]% n  B7 ~6 a  }
enum CursorTypeEnum
, c! `- e4 h0 ^% q& b{* B: t$ t; [3 j, c( M; I. A
adOpenUnspecified = -1,///不作特别指定
/ u! }0 I% |# OadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
% \2 h6 q8 v, ^3 o- c+ {( wadOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。0 c, U: g5 t/ M) V

! m& Z9 S% @1 J/ O. jadOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
/ u1 k, Q" J$ c0 L' X; W2 AadOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
' o+ K) ^8 W* p4 m+ ?7 y* x};
, A* o7 d9 O5 f  o+ e: W7 q④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
2 c+ F2 Y0 g! p" P8 J
  v; {; M; d9 h: E, o9 x% }enum LockTypeEnum( E0 Z, f: [- S3 R. ]
{
  }/ Z, S& k! O% ?1 ?& V& PadLockUnspecified = -1,///未指定6 y9 \, L8 f6 ~$ p$ i% o( d
adLockReadOnly = 1,///只读记录集
! q& I. W3 Y8 e: N3 q9 f' W1 PadLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制. ^# O7 r! i' a8 h7 N3 o% ]3 ~0 i
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
) m+ J4 w1 W# M0 F) AadLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
4 g6 F2 Q9 M5 V' ~3 h1 Z}; : M0 C" v  q+ |8 _$ @4 S) A' L

# w; N+ y' P! i+ ^" a; H) G⑤Options可以取如下值之一:5 K0 C4 G2 F- y. H/ A& o4 v
adCmdText:表明CommandText是文本命令% l; i6 A- O9 g  {& j+ p6 N3 X
adCmdTable:表明CommandText是一个表名5 ^# T+ z( s+ X
adCmdProc:表明CommandText是一个存储过程5 ]; o3 i9 h: M
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-4-17 01:43 , Processed in 0.427333 second(s), 52 queries .

回顶部