- 在线时间
- 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命令并取得结果记录集1 t5 j- d/ H( U; y$ ^ g7 f
: M! M5 g4 B/ v3 [1 o( Q8 }4 o& K
为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;/ g9 G# |9 k# W1 z% X+ P A
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");; {, A! g( B) M& s6 d
SQL命令的执行可以采用多种形式,下面我们一进行阐述。
+ H1 o+ A! E( m! Y- d
+ P b& C; u- {! G. R (1)利用Connection对象的Execute方法执行SQL命令
1 U2 G5 [* P6 k H: X1 z1 s L1 w+ F( o4 z& ^
Execute方法的原型如下所示:' e3 P% J+ H- d" {+ h+ Y: `
. v t5 q6 z# f+ x% i, x
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) & g/ }! _! b" j; z: B% T J
$ [, b. U. k# ]8 R* q* `其中CommandText是命令字串,通常是SQL命令。! o+ _/ }! G& V) ]7 V' a
参数RecordsAffected是操作完成后所影响的行数,
) T0 z5 ]/ T7 e; ]/ @参数Options表示CommandText中内容的类型,Options可以取如下值之一:( K" s/ o2 D4 q, I' S4 I9 k* ^
adCmdText:表明CommandText是文本命令4 h* p& `! `) e: \( W+ k4 r( E
adCmdTable:表明CommandText是一个表名1 G$ k5 B1 Q1 H* w
adCmdProc:表明CommandText是一个存储过程3 L% w, K% o) R$ ?% _% F+ w U
adCmdUnknown:未知
& I2 X) j( N' F+ @
9 k9 s. j" F0 o2 d) oExecute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
; S8 p' s8 ~- \0 Z1 O O! l_variant_t RecordsAffected;" D: `9 L. H/ P; K
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday$ T! j/ k2 p9 ~( z) x; b
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",5 }- H `9 t6 I
&RecordsAffected,
1 E6 E! j, F0 s4 \1 w+ badCmdText);' b- h3 i c0 u
- d1 |5 X- v7 z9 ?" u9 }4 @+ ?
///往表格里面添加记录
% r# {6 e) \; s8 J. g& Vm_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
- P1 K; T$ M6 l) M
. X8 B) o9 f/ P! P1 T* _( w8 a/ x4 D///将所有记录old字段的值加一
! h& N9 b' Y& N) R% nm_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
! f2 a u/ B# }0 c: c. M% {
, ~2 [" h0 k. |) \+ }///执行SQL统计命令得到包含记录条数的记录集7 T4 P" R$ s: @ ^& K$ M
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
. P8 d2 G. R) T) Z0 q. n3 h& t_variant_t vIndex = (long)0;
" G" W. P( U; C' C# I_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量% b( M( c5 _# T9 ?7 [6 O' B
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
9 n9 ~. t. E2 p1 d. }m_pRecordset->Close();///关闭记录集% A* ], I# B1 |/ m
CString message;
. V! d" M x: Y+ ~message.format("共有%d条记录",vCount.lVal);. j+ O: Q) P5 O: |
AfxMessageBox(message);///显示当前记录条数
6 ~0 D6 _6 n/ p8 m* `+ B, T# [: o
- G2 z+ N f* j9 V1 Y" [(2)利用Command对象来执行SQL命令 0 Q. X$ Q) o; K! {6 `4 g
" J2 U5 v/ w4 i4 h7 D' v_CommandPtr m_pCommand;
" e/ {, E3 ~! R& j/ hm_pCommand.CreateInstance("ADODB.Command");" m, |) b3 z" [4 F& H
_variant_t vNULL; O. E: V) t6 |5 N. A! _; d
vNULL.vt = VT_ERROR;9 A( \& H9 H( t7 Y0 W; P; f& u
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数+ r' b0 N4 P& i9 K* g
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
! ]3 a& G+ w" {4 g# W( lm_pCommand->CommandText = "SELECT * FROM users";///命令字串
2 i' A2 K7 z: g3 j: _3 r- _m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
4 f v8 R. Q7 {# T5 O }
* C# A7 x4 h3 a/ i# L 在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。 % F7 }- B1 c/ ]: h4 \
7 D5 B4 |* ?% y5 w# v (3)直接用Recordset对象进行查询取得记录集
+ ^( B- Y. y: O" Z3 Q
& c. x2 o6 M) i; ~ A, r 实例—— & p* k2 ]5 b7 Q, l% u6 H
# x4 ^2 x" D, ?% a$ l/ e
void CGmsaDlg::OnDBSelect() * `* Z: G( t- q, l- x" H& ^) w
{
- k6 n8 p0 E( e+ k// TOD Add your control notification handler code here" I( r6 V% o& l* G9 x. L
_RecordsetPtr Rs1; //定义Recordset对象5 x" N8 _3 V9 U. w; x
_bstr_t Connect("DSN=GMS;UID=sa WD=;");//定义连接字符串
$ |5 r: g/ G6 r1 x* J6 A_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句& T1 a+ u; w6 m: \ m9 _
::CoInitialize(NULL); //初始化Rs1对象0 y2 C% O: V. K6 o7 F' Y# Z6 U/ D+ g
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );0 w! x& I/ |/ k5 r R! {
//省略对返回值hr的判断 , B! J* A9 U* y# i
Rs1->Open( Source,; p* o7 d# M8 R7 B
Connect,
, G5 `! `6 O$ v) K6 f; r) HadOpenForwardOnly,
8 Z! {: E" N) F, SadLockReadOnly,
# C# L3 i2 P- _' I/ A-1 );
1 f# C- `# E% M* N# F( @_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
3 X- u* z/ x6 ?CString strTemp=(char* )(_bstr_t)temp;* W: T; ]- H8 r8 `! T+ _5 p
MessageBox("OK!"+strTemp); W% F% a; f4 k V5 [, r
}7 A8 A) I, p6 n/ f
7 H7 C6 ]- x% f% {, ^ N- X0 B3 _/ O例如 . Z" Z: j4 O+ T- m
m_pRecordset->Open("SELECT * FROM users",
9 A% @: F4 r( l. L4 Y2 ^_variant_t((IDispatch *)m_pConnection,true),
. E$ o* z9 {2 H% ~+ I& `& ^) VadOpenStatic,; U, b1 }2 ^/ x& C' ]& |
adLockOptimistic,) m' m$ r) I) v% O* W4 N9 C, c
adCmdText);( Q" J5 h. a& [( `7 L! ]( R4 B
/ y0 Z' }$ p' D+ E4 L& e# YOpen方法的原型是这样的:
( m8 n8 p9 Y6 g- UHRESULT Recordset15::Open ( const _variant_t & Source,
+ c }3 T1 }0 q& Y& l5 Pconst _variant_t & ActiveConnection, & P& ~+ v0 _. e6 A- y# [
enum CursorTypeEnum CursorType,
8 S8 N' t. U5 N" H2 f/ m) R; Uenum LockTypeEnum LockType, 6 }3 J% k! f% {3 y$ o$ g
long Options )
3 Q3 h0 k$ A: Q7 s# L, X, B( R3 q
- i* C1 W( L6 _. \, ]* O其中:
1 b' |; O: O3 {9 {+ [& l
$ l( q T1 M% Q①Source是数据查询字符串; ^2 k' l0 E' s7 @
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象) ' R6 z7 \$ H. i' }. x4 l2 } h
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:* G& K. n ~ o- R
3 j' D" d; L8 ~enum CursorTypeEnum) f/ y+ }" Z, x; r1 f, [3 Y9 a U0 U
{5 N* k+ N3 L$ E, [& l- p
adOpenUnspecified = -1,///不作特别指定
6 F# A. _/ o0 f+ ~2 yadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
; h' D+ _; A n) k/ _7 b/ @adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。% K1 _8 _6 F2 o2 _
& ~8 d2 _, P$ y( X0 C4 T3 Q* a: f* p( \
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。% A" U) i1 v* K# _4 T
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
/ ~" p- m, L: \8 p' g};
3 J4 s# S7 j2 M$ h8 _④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:: \1 _) X+ z* n- V4 a9 \& f
0 D( q; o% c+ tenum LockTypeEnum$ d- N: f5 j8 b m6 I n+ ]
{
+ e2 V4 ]1 p& q2 |adLockUnspecified = -1,///未指定4 L7 M) H. Q9 o8 g1 L8 o) |7 U
adLockReadOnly = 1,///只读记录集
# f5 m0 C9 Z3 C5 ?adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
' e, Q: O7 ?" l4 J& o# a# T# f; \adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
+ P9 o; N2 d+ {. C6 |adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
* ~& B* d- O3 v5 W};
) r- Y; i$ P1 d, K+ X, i& U" M) n; j( {! _. y% J" o- Y
⑤Options可以取如下值之一:7 a0 n7 x& H+ z, y4 e
adCmdText:表明CommandText是文本命令
% g" B: F5 y- p9 f8 A SadCmdTable:表明CommandText是一个表名
$ i j3 A$ }! Q! Y3 \+ qadCmdProc:表明CommandText是一个存储过程- K0 D; E) {6 g1 A2 m. q' R0 q
adCmdUnknown:未知 |
zan
|