- 在线时间
- 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命令并取得结果记录集0 N& q$ C3 j5 ^9 Y7 ?
$ I H2 T, q3 F h1 F! w- L 为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;3 p- [) E8 R# Q7 ?& g/ k! c' i( T7 P
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");/ }6 y$ y4 n: L b9 @: r0 \4 n2 v- q
SQL命令的执行可以采用多种形式,下面我们一进行阐述。
, a" c* Y% b5 [1 d% r
; k3 K& X! p! i (1)利用Connection对象的Execute方法执行SQL命令; N5 E4 r: n$ {& {$ b
1 P# f$ S, G& d( E( _8 k Execute方法的原型如下所示:
2 V5 z* n8 ?0 k* p2 k1 _( {7 ?# L; c: H0 z
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
8 s7 Y @5 |; [" P, o$ u( _$ j+ h# _7 M1 W1 U
其中CommandText是命令字串,通常是SQL命令。
U! b: S6 E; r/ b6 G% Q! }参数RecordsAffected是操作完成后所影响的行数, 7 {4 {% }# Y) P0 B
参数Options表示CommandText中内容的类型,Options可以取如下值之一:. n( s# \5 `; s- F' @8 G* K) o3 x
adCmdText:表明CommandText是文本命令
I1 z) A% t" y" h, O" R+ LadCmdTable:表明CommandText是一个表名
2 J7 }- p: d, t) x/ x, ^: LadCmdProc:表明CommandText是一个存储过程
8 z& P; g: A X. f. M# p3 N2 ^adCmdUnknown:未知
+ d2 ?( o* J- ~2 L- B1 D) n2 q- C
3 E$ T4 T+ Q: O- z6 W( JExecute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
& B$ x: k* H. U: e& {9 n" x% Z_variant_t RecordsAffected;+ `, b* c8 s" W: ^4 n
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday0 O6 O- ^; M# O) ~
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
( w/ n$ I5 H+ w5 m6 T&RecordsAffected,
, u) u; l; m7 _, `: e& h% {- ?adCmdText);
- z. e1 q4 F/ W, @ s0 z3 U* D0 M! }5 j4 C
///往表格里面添加记录
8 E' u/ ~- P& I: B% T Nm_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
1 F$ x/ H# ?$ g( Q" W1 w0 a! E( _
; w8 c, \: b4 i! f! L) Y1 a///将所有记录old字段的值加一! j, u$ x( s* n7 c8 c* H. H
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);& R; h e h' }4 s
1 w; I! I+ j) |& l
///执行SQL统计命令得到包含记录条数的记录集) h& S! Q2 K8 O& i' k
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
' W4 Q0 ?+ @# C6 ]_variant_t vIndex = (long)0;1 @) l6 Z `5 v, K/ c2 ]# Q
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量: D1 `7 k: v( M+ m
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
9 U4 K8 W6 Y4 I; E) B6 T0 `# tm_pRecordset->Close();///关闭记录集- B3 Z @& |" x3 X* E0 ]
CString message;. M, u+ A$ j. N4 f
message.format("共有%d条记录",vCount.lVal);
5 w4 o' ]$ o3 F; }# }AfxMessageBox(message);///显示当前记录条数
) t, I6 Q8 Q# w- m$ D# Y5 B( V& O. @
(2)利用Command对象来执行SQL命令 4 ]! O$ c3 v5 g% _! w- H4 f' C! d
! E7 _ p6 N3 Y( r! P8 L4 }, ]5 ^
_CommandPtr m_pCommand;% Z2 R0 j. n- u% N: W0 V
m_pCommand.CreateInstance("ADODB.Command");; M- |6 R2 C# f5 Y8 G. N: d
_variant_t vNULL;. S H- U) W$ k" T T0 W7 [
vNULL.vt = VT_ERROR;% k+ W9 }- } g$ i9 U0 I3 w8 N4 n* z2 C! E
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
/ L1 X' e, D& D+ d6 E! N% I0 ?- Xm_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它" E7 ~* _" | }7 n
m_pCommand->CommandText = "SELECT * FROM users";///命令字串. J% R) d: A7 q
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
/ Z' N* |* ^ A: C
8 b7 U0 ]4 K8 [ L 在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
+ N3 }6 y( H/ j
9 X$ `$ R. }; l) F/ A5 b (3)直接用Recordset对象进行查询取得记录集+ U, V0 k {& |- w+ N& `9 c
0 @. M! t2 ^" d# h
实例—— 6 C1 L+ C2 a7 Y/ _+ v% j, c z9 I
+ V1 Q5 T: f; P1 }
void CGmsaDlg::OnDBSelect() * ?. c8 d5 |! L: D
{6 ?0 m6 w+ T% ]( i7 @4 w- U0 s
// TOD Add your control notification handler code here$ h, n3 G u4 R+ R
_RecordsetPtr Rs1; //定义Recordset对象9 e% V/ {. u/ a m# p" o
_bstr_t Connect("DSN=GMS;UID=sa WD=;");//定义连接字符串
9 h$ V$ W( h- S0 @: B: t4 y8 @2 E7 R_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句! O: s" O. w& `# u
::CoInitialize(NULL); //初始化Rs1对象
+ q7 q5 X3 h0 ^0 UHRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );# h( X4 {; F, m& @2 }
//省略对返回值hr的判断
3 V- S0 O+ O. v+ k$ vRs1->Open( Source,
; Y* B3 L/ f: s2 t ?5 ]+ }Connect,+ u: T+ R* B5 o0 _0 Z8 `2 ]+ m
adOpenForwardOnly,
3 \8 C) J$ A0 i; ^- g/ xadLockReadOnly,) x, k5 X6 T" d/ }1 O) N( m) r2 @
-1 );
) w! v; N* A' F4 Y8 `' z; c_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
: S; Z$ F- I0 ]- W" l9 O4 ?CString strTemp=(char* )(_bstr_t)temp;
7 i7 c* p; j) \2 n% G' d0 y3 }MessageBox("OK!"+strTemp);
; o( t6 v; ^" N; V F. J# Y}
" z" o/ o/ t" R
6 J8 R) k: Y2 t例如 8 q7 F2 I2 }* S# J* J
m_pRecordset->Open("SELECT * FROM users",% w" `! U) I1 f2 a3 b5 k9 `
_variant_t((IDispatch *)m_pConnection,true), t& G( P. g$ [1 i) b" H- d
adOpenStatic,
, f. p2 O4 H' V* x* G5 DadLockOptimistic,
, ?& e. X2 }7 e( l+ T7 B5 y3 RadCmdText);
7 O: D, t+ L, b- O" C
/ h5 q& m- f( x7 o1 n* T WOpen方法的原型是这样的:
2 {. {, s [" r, YHRESULT Recordset15::Open ( const _variant_t & Source, * D3 x+ s* e3 e- K0 e% N
const _variant_t & ActiveConnection, 1 j# [, x* a4 L* u o, J k9 S
enum CursorTypeEnum CursorType, 2 S: R6 N2 M& f
enum LockTypeEnum LockType,
5 g4 g T" r5 \ m; j# h4 Vlong Options )
( o/ Q6 d9 j: f" W
# J* N- J: [3 m# ~' V其中:! J d8 Q# G. g8 z+ o) s9 n; o& J
% K) ]) g9 d- _1 X' s, r
①Source是数据查询字符串
- p1 H% V; v5 W6 R②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
' O5 W5 ?/ ]( [0 _9 @$ s③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
* b5 C3 n$ Z ]$ W* s0 V
# g: I- [& y: j, t) }3 N) uenum CursorTypeEnum4 I) H- }, d% _5 l
{
6 R/ O6 |8 {/ d$ m" m. ^3 b UadOpenUnspecified = -1,///不作特别指定' @: f$ F+ _7 ~5 x$ W# D
adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
' J3 e1 ?2 r# ^& sadOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。/ e: a! i. l2 C0 p+ u3 s
* c0 p* F* v% t- D1 \adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
$ @5 H) @. ^8 Q) O& PadOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
% D1 A. o5 R8 X) J, u1 X, U};; `% Y# S0 i# I; ~8 p& }9 c
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
! O* G" j" M* D! L1 |1 k2 }1 a4 Q! R3 G+ ^$ P' t
enum LockTypeEnum
- o7 T: ?0 s. o7 g4 p7 g8 r3 S! V{
& `. {) k% M( I) D Q4 MadLockUnspecified = -1,///未指定, @% ? w8 m: q0 R
adLockReadOnly = 1,///只读记录集; j; q0 j- s$ k
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
& ?' @8 c& i% S( uadLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作$ w8 a: ~) u' }0 s
adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。: W" M7 w" P/ L$ F
};
/ E( l9 g# J3 F8 f: w
1 f- B+ A- Y+ w( _6 \' T& @% m⑤Options可以取如下值之一:
, i& ^+ I- N9 s i3 o. padCmdText:表明CommandText是文本命令
! p9 f' i" I5 H0 Y' M/ Z6 g$ H0 GadCmdTable:表明CommandText是一个表名
& j6 V3 t3 `7 B5 Z( H$ n1 oadCmdProc:表明CommandText是一个存储过程. P! k. C) ^; K. Z7 G
adCmdUnknown:未知 |
zan
|