QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集5 B6 \2 {/ Q! h
1 x: P+ e, d3 B, \) e  k* k
  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
* S7 P/ G9 m: _  Q4 U8 P9 o并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
' l9 F$ v8 K) ?SQL命令的执行可以采用多种形式,下面我们一进行阐述。( X( \! x0 [" B

. G7 G6 m% f3 `7 R9 l  (1)利用Connection对象的Execute方法执行SQL命令
" s8 G+ K! h) |5 B4 a8 g2 o* h1 I' @
  Execute方法的原型如下所示:
; h7 k1 M( C$ D* Z6 V2 ^& c
2 P# L+ y+ r7 t% o+ _2 Y0 c_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) * u: Z9 y  s  ~' }: ^+ T) f

# @. {" X  u2 f' d0 P$ L' o其中CommandText是命令字串,通常是SQL命令。* u2 {% u& d: G- q) `
参数RecordsAffected是操作完成后所影响的行数,
# b9 E; `5 N: a7 s% [: X参数Options表示CommandText中内容的类型,Options可以取如下值之一:
2 K* N* M2 b, g+ B0 q* n7 C0 f; x2 G0 MadCmdText:表明CommandText是文本命令
3 j" R+ k) T# I0 m9 ]' DadCmdTable:表明CommandText是一个表名
# ^4 c" b! `1 @+ FadCmdProc:表明CommandText是一个存储过程
! A5 ?$ G8 D/ }! I& jadCmdUnknown:未知
- k( g" a) H6 Z8 F2 B  E3 `& t. E
; W7 x* _# e) O. }Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
8 T; [) d0 C( X& D_variant_t RecordsAffected;: z2 t' }# J( Q
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
: ?+ i! ~4 O9 q; V5 Qm_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",5 E7 w* v8 v; B3 ]
&RecordsAffected,
9 _4 a3 G( O1 u+ }* M7 R0 R2 G$ vadCmdText);% F1 K8 j+ K/ h! S
6 `, q/ _) `+ E/ Y7 K
///往表格里面添加记录
8 F) \; V6 v/ O( i* f- H  S8 om_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
4 a! }; D( G" z6 {9 T; g6 j$ u# `) Z. V8 G! p8 O- X
///将所有记录old字段的值加一
7 `) X1 r8 y, O( G8 d' Q8 |m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
1 [; T2 \  b5 C& ?  M( ?- a; B+ s( L. I' }. G6 e: `8 @
///执行SQL统计命令得到包含记录条数的记录集0 P3 W9 M4 K! @/ w4 ^. S
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
5 U2 W2 t" E9 `% h: p_variant_t vIndex = (long)0;0 h% O2 @' A8 {
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量" F: [/ ^, Q( [
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
* D' ]& z6 ^3 l- v$ o; r7 um_pRecordset->Close();///关闭记录集
$ }: t" x" u: k9 SCString message;
# s& I4 l: D. h, G& amessage.format("共有%d条记录",vCount.lVal);8 r2 s- L  E3 |( v8 k
AfxMessageBox(message);///显示当前记录条数4 }" D8 j* P$ K7 q7 W
" B. j! a% f  O
(2)利用Command对象来执行SQL命令 ! n9 ^8 Q& i  ^5 |+ b

- `, s3 o' G) @- d% ~" ?: l_CommandPtr m_pCommand;. q0 f& R3 B! w* h6 }. ^
m_pCommand.CreateInstance("ADODB.Command");- A0 U8 R* N% f# f. e
_variant_t vNULL;
2 d& m; O0 g7 C. K; @2 q8 |' PvNULL.vt = VT_ERROR;
  `- ]+ i- ]' c2 @9 v6 nvNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数7 [: D: b% q5 \4 \/ \  o: u' g# i+ c& s
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
6 f; f& `" m! H7 i6 im_pCommand->CommandText = "SELECT * FROM users";///命令字串
' {3 `+ |3 l; A) e7 F3 j7 Qm_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
1 a- |( _- l! E3 f$ M
# m/ B5 [# b1 b! c! o1 ~4 G  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
* R& a( u! y6 W$ C4 z) x7 ]
0 a- `) F* g3 {, L' i; o0 u  (3)直接用Recordset对象进行查询取得记录集' c* Z. n1 S7 M2 I5 i
3 j% J. S  s; p8 R$ F' p
  实例——
9 o) h5 F  g- A6 |* t( l8 h* m9 V. a+ f
void CGmsaDlg::OnDBSelect()
( M) w3 I5 s1 a{2 d2 A9 U4 {+ l; l% K. {6 q
// TOD Add your control notification handler code here! t; m" K$ d( _/ j) s1 R7 c
_RecordsetPtr Rs1; //定义Recordset对象4 Z( ~: ?' e( s2 f; j' M5 C- k
_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串) E) Z9 W& {! d& D( c
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句4 H5 \1 @: R6 `2 v
::CoInitialize(NULL); //初始化Rs1对象. s* N/ b- J9 o1 ]
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );7 `! r6 v' I7 ?3 {4 o
//省略对返回值hr的判断
. v/ F% q8 ]) y( R9 XRs1->Open( Source,
6 g4 f# `3 F6 \5 ^' S1 e$ uConnect,' l/ p8 ?+ z% L7 P
adOpenForwardOnly,6 d' X9 q6 j0 J: d+ v# p
adLockReadOnly,
( u/ \, S7 P4 \" u+ x0 v' h' l2 W-1 );
( T- k( W( l+ v: K_variant_t temp=Rs1->GetCollect(_variant_t((long)0));* q' ~4 \/ B. B# F+ y
CString strTemp=(char* )(_bstr_t)temp;, y& [( S: ]* \8 Y
MessageBox("OK!"+strTemp);4 l* p$ `7 B4 A7 Z8 E" f
}
; e; U0 \* Y# ?$ }% \" a. D5 _. X! p# C4 T
例如
% a6 N2 |: |8 l8 ]1 S& |' ^m_pRecordset->Open("SELECT * FROM users",: J0 c2 l2 M) Q; B) @
_variant_t((IDispatch *)m_pConnection,true),* B# h5 a5 E; c# S' o5 l* l( f4 S
adOpenStatic,
: Z! v" m1 M& E. Q$ e% Q6 NadLockOptimistic,
* Z# s- h2 p- s. T$ c' BadCmdText);/ r' ]* `; ]$ s

8 |4 d5 q! ?4 v0 X8 t  \Open方法的原型是这样的:
) h; P! O9 `2 i% T$ oHRESULT Recordset15::Open ( const _variant_t & Source, " D1 G$ n5 E$ b' |+ G# T
const _variant_t & ActiveConnection, + s4 p# a) u% v) \
enum CursorTypeEnum CursorType, # U4 Z; }5 Y+ X' {6 W: T0 k: G5 `
enum LockTypeEnum LockType,
6 Z! }+ e. s1 U' t4 g; c) jlong Options )
: Z3 K+ E4 {2 _  H  h8 q: i) n, i, e9 w+ a1 b) \. Z- `6 J
其中:
% j( x- f& |! O3 q  t- P* `- ~9 D/ _) \" x: i" e2 [1 u& H
①Source是数据查询字符串
2 j1 m  ~/ j6 x- d$ R$ h②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
: n2 x5 T+ q. y* q; @$ y) h9 O6 f③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:0 Z. N& {& I3 f2 P
8 G9 w6 f9 n( |4 s
enum CursorTypeEnum9 ^* {/ t' b: d% S+ D7 e% Z9 W( Z
{
* f* |* Z5 q6 g: S8 Q' O0 TadOpenUnspecified = -1,///不作特别指定
- @. N% c& _/ x6 y8 l  Z9 ?6 vadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
" Z( m( ^  i0 m: J: q4 YadOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。& @1 E6 g; {0 e8 b- Y7 I
5 J! d8 X' {. a1 K0 P: d8 x
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
4 j+ p+ p$ N8 d! W9 U: HadOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
6 M5 V7 @; c2 h& X$ ?};- n5 X2 h- h: h9 j  |; t5 L* Y/ N9 C
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:- O1 \/ v( j* C/ r5 o
/ K0 w/ g0 |3 G
enum LockTypeEnum, M5 f# h7 b) s/ B* e
{  ^. E8 a3 Q0 l. s
adLockUnspecified = -1,///未指定
9 n4 X/ j* W' L( P! t, o* @adLockReadOnly = 1,///只读记录集
4 F* q0 ?' g. o0 madLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制' y, p7 ]* C8 |$ q) z5 r9 C5 B! r
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
; t: m8 @2 g/ s: R4 yadLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。8 L# W5 P$ h: a
}; + b2 z5 P$ X0 a

$ w+ F! n$ ^  a8 S0 R9 \⑤Options可以取如下值之一:) `1 Y6 w: H* A# T5 h( z
adCmdText:表明CommandText是文本命令
/ P( T2 p4 h0 T% ~1 }" G+ n  RadCmdTable:表明CommandText是一个表名: D0 ?5 B, k' u! B" X; S# E2 d) _
adCmdProc:表明CommandText是一个存储过程
: ^9 K1 ^8 z7 qadCmdUnknown:未知
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 18:52 , Processed in 0.562854 second(s), 52 queries .

回顶部