- 在线时间
- 0 小时
- 最后登录
- 2007-11-12
- 注册时间
- 2004-12-24
- 听众数
- 2
- 收听数
- 0
- 能力
- 0 分
- 体力
- 2467 点
- 威望
- 0 点
- 阅读权限
- 50
- 积分
- 882
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 205
- 主题
- 206
- 精华
- 2
- 分享
- 0
- 好友
- 0
升级   70.5% 该用户从未签到
 |
4.执行SQL命令并取得结果记录集
; R6 y: h% o0 t5 }# O0 \1 s, V+ c% v( x
为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
( @" g. I" i5 H并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
" X( Z4 T5 K, _, R1 `SQL命令的执行可以采用多种形式,下面我们一进行阐述。8 a4 d3 w) w7 S8 u
P) M6 W: T/ U9 ?1 S
(1)利用Connection对象的Execute方法执行SQL命令
7 _" V+ Q4 G" d
) W) P E6 {0 ?: ~% O2 t. `' b Execute方法的原型如下所示:( X% _: `( {7 d7 F. @
5 b& p y, ?+ C) U1 U. s_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
9 w# Q ?" @' z1 ]$ i/ j+ o( B' p/ o, L6 W* j' y
其中CommandText是命令字串,通常是SQL命令。8 _+ k- ?; P" z% a. K) ~% N
参数RecordsAffected是操作完成后所影响的行数,
& |+ T) ]7 w$ Y$ O5 S参数Options表示CommandText中内容的类型,Options可以取如下值之一:
. u! i7 y. | yadCmdText:表明CommandText是文本命令
% |2 o. j( b6 @1 X! D$ ^adCmdTable:表明CommandText是一个表名! _# b" w$ y! g. V3 y
adCmdProc:表明CommandText是一个存储过程' w7 Z) c4 a+ k& U& f1 m6 K/ a
adCmdUnknown:未知$ h( J" z u1 t! J+ O$ ]+ \
1 j4 p8 N! V- ^0 i/ m" _
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
5 m7 O, }/ V+ }5 Q! h5 E_variant_t RecordsAffected;3 X& u, `( ?" g0 n2 Z" A" b' L+ b
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday& E5 m, z8 o3 q! i2 t
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
. o9 Z4 x1 s& S7 W' f" L8 u( x&RecordsAffected,* s/ q) Q$ k4 m# t9 h y1 s3 D
adCmdText);
: g8 v. Q8 P6 e( G# {
' {+ n8 v/ ~- z0 p9 C. u///往表格里面添加记录4 X$ S. L0 d9 W
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
) M, L4 `- `" Z; e; H
/ q0 |0 C0 |+ h) a. u. c0 U///将所有记录old字段的值加一
! F4 j/ G* e* ]1 u2 p, |2 Sm_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
5 F2 a# e4 h$ s( g% X" M! c! ~$ T# Z) h" f9 m' p1 ?& J
///执行SQL统计命令得到包含记录条数的记录集
' y: T2 P* M, h# H9 b: Z# b! am_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);. O- K' `- J" l z+ |
_variant_t vIndex = (long)0;- h. S3 p3 D* H* r6 ]8 ^% S
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量+ D* M% K+ {7 w) V F7 J
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
1 K! V; Q) Z6 z8 zm_pRecordset->Close();///关闭记录集
% ?( @. a" L! p/ A7 Z- fCString message;
# |( O. s- Z$ f) g- p4 kmessage.format("共有%d条记录",vCount.lVal);
, v, s& R1 T. qAfxMessageBox(message);///显示当前记录条数
( K& P! e$ S: A# R0 ?1 b, |2 Z( ~3 j* D T
(2)利用Command对象来执行SQL命令 ; \1 c- o- r3 \: b: k0 l
$ n# j- J" b2 [4 w2 D5 n) [9 w
_CommandPtr m_pCommand;
3 w8 O) T* e0 Y( ^. U. ~6 E; e" ?m_pCommand.CreateInstance("ADODB.Command");
$ }6 r6 u2 Q8 o+ T. Z! h_variant_t vNULL;
3 d* {# c. d9 C, UvNULL.vt = VT_ERROR;1 x% V W# f. a. P$ X3 m- _
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数8 D5 Z; {; _% q
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
4 c2 O0 v9 ]8 n/ U2 Qm_pCommand->CommandText = "SELECT * FROM users";///命令字串
! f& G, K+ n# @1 A( u- E# dm_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集% V9 s- h, P4 u* Q! X* N+ \
2 L0 F U- e* W+ b3 J
在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
1 [8 I; r9 j0 V6 }
# `/ S3 G2 U& J) x! x (3)直接用Recordset对象进行查询取得记录集# a9 W" U% q5 A. ~4 z3 n4 ~! P
2 q: X3 {. r% j& \! c' B" { e% ] 实例—— 7 p1 G/ I {+ O6 r7 F
8 u% W& H2 M& X" @2 Dvoid CGmsaDlg::OnDBSelect() 1 [% \" x; ?. U& B: m/ c: c% g
{
; W8 H6 |0 [6 B& P" X, E! M9 t// TOD Add your control notification handler code here
6 s. E* i, ^! { E; a* M; d2 x2 R( h6 N- q_RecordsetPtr Rs1; //定义Recordset对象: m$ b% h9 u6 O7 M! E
_bstr_t Connect("DSN=GMS;UID=sa WD=;");//定义连接字符串6 |, N( G$ J$ N# n* H+ m& Z
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
! s+ y+ J" D% P& q::CoInitialize(NULL); //初始化Rs1对象
0 \- z( n/ L, V+ \. B# x$ ~0 ZHRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) ); n3 h- u k, j# _% g( g' E
//省略对返回值hr的判断
+ j3 S1 Z+ W0 P' y& I4 DRs1->Open( Source,4 `# }, e- c0 x
Connect,
) S. e F6 x+ OadOpenForwardOnly,
, g! c; `2 B" p/ E) VadLockReadOnly,
$ j a/ ]: d, R6 K-1 ); 4 A2 r* z. g* x3 H# h. q, n3 U! K
_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
9 } U5 }( }6 |CString strTemp=(char* )(_bstr_t)temp;
2 S- |1 U0 g, Q( |# d7 BMessageBox("OK!"+strTemp);
) Z) b4 p, a: b) P) h! U7 }7 P1 y4 [}% x. [! i8 J+ V* ^; |0 a
' s1 k$ p, y' L8 w% o6 M9 f" f" j; P
例如 0 q$ k+ G. A# \' i. R% P" w" K
m_pRecordset->Open("SELECT * FROM users",
7 O. R3 L. w' o9 ^9 y& K& q! x1 c_variant_t((IDispatch *)m_pConnection,true), H1 D% R& d1 G' ~, q
adOpenStatic,
! y, w4 {( `- ^2 o8 radLockOptimistic,8 {) ^+ X0 k( j$ f
adCmdText);
" m( v# c" ^% u6 h( ^* B5 W# E
5 J9 P1 H) C# J! FOpen方法的原型是这样的:
; N! y- l/ X9 [' N( J6 H2 kHRESULT Recordset15::Open ( const _variant_t & Source, # {! O; Z2 }. L" W
const _variant_t & ActiveConnection,
* Q/ M9 s3 {0 t* z+ ^) zenum CursorTypeEnum CursorType,
+ Z( g* c# e- q; Q! k benum LockTypeEnum LockType, + W5 S$ ~* b! q- j2 t3 {, e
long Options ) * c- S: B/ w5 y0 ^ \
* Z. u( y4 @; h3 \
其中:% q( P8 L" _. ^/ d1 ?2 e* F
/ J, n, i8 X6 W" Y9 @. Y
①Source是数据查询字符串
: Y' r! L, X. ~4 E+ A②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
8 r; y1 |7 f6 w6 M③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:2 F- y* Q' O4 S) ]2 \4 Z
* U |: V% {# v9 a1 ~( A
enum CursorTypeEnum" \* d: w% b5 ~; K# V, e# M
{
9 z/ }" C; Z, N3 kadOpenUnspecified = -1,///不作特别指定6 J, i2 M- S; \
adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用5 n7 w' B# B( P! X
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
4 E q/ e! I, s' N' ^7 ~' t
4 T. z/ |) ^ M8 {3 RadOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
$ j; M, ]: y1 D( |' T! Q+ D% @adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。5 w1 o( B, e6 O
};6 j' o2 z9 V: h0 _
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:2 K% y, C) ?! P
. a8 p' Q, e3 c' a n; K
enum LockTypeEnum
2 e3 U% ` i) G8 v5 r# B, G{' Y% |( _- W# r& ^' _8 {5 E
adLockUnspecified = -1,///未指定- K+ `/ G0 q* y$ A6 t M# l m$ u
adLockReadOnly = 1,///只读记录集
& M" W7 l. |. K9 p2 qadLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
( `& i9 h/ U MadLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作% A8 v$ ^# {& H0 i
adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
4 \( Y4 Q' v3 @( `};
" P: O0 }8 F4 A9 Q/ v' c9 Q& S2 g1 ]% B1 Z
⑤Options可以取如下值之一:3 F: k5 K" Y1 F% B, f9 ?1 l
adCmdText:表明CommandText是文本命令) L/ D4 Y% d# V. e* }
adCmdTable:表明CommandText是一个表名/ l" s0 C* G3 z$ a2 p, I
adCmdProc:表明CommandText是一个存储过程
! G4 x$ _ J: t! radCmdUnknown:未知 |
zan
|