在线时间 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命令并取得结果记录集4 @6 d1 s7 h2 m! ?' ~1 n) ~
8 Z, K w9 e, g" W! V3 X 为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;' s- w5 j4 E' R, k
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
$ v, Z# [3 p2 d1 u& |* ` SQL命令的执行可以采用多种形式,下面我们一进行阐述。
. h1 ~( Q- X3 d% ^3 o! d $ r$ x3 ?. _5 z* k# ~5 ?- m
(1)利用Connection对象的Execute方法执行SQL命令7 }+ C+ C, C/ m) m, y' {
2 f+ {1 P% k- u# R2 f" ^ Execute方法的原型如下所示:; H* |; ]! z7 x) Y d! A
4 g/ Q. b" _- C' T, x0 A$ R
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) 1 A, V, z* B* |0 o; k1 T
F/ f, S$ e* r+ i, w! F* T
其中CommandText是命令字串,通常是SQL命令。
# ]5 Z6 |% R! H* U( a! i8 g 参数RecordsAffected是操作完成后所影响的行数,
- E6 J1 ]4 q% ?* K4 m0 [4 d& M 参数Options表示CommandText中内容的类型,Options可以取如下值之一:
6 ^, L' u, ^ Z) u$ V( p adCmdText:表明CommandText是文本命令
" e4 g& e0 C+ k/ m, M5 r adCmdTable:表明CommandText是一个表名
4 w/ w/ g: Q# i& l adCmdProc:表明CommandText是一个存储过程
0 P" `4 ]4 G' h, `( h# a% u7 M adCmdUnknown:未知' l8 N8 i" I( I. R( L
& \9 z B( C, S( _: w1 m& Y
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
, X0 p' u$ J0 ~$ B _variant_t RecordsAffected;6 F" K; X* z }! `0 ^7 Y, A# H0 y
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday/ m/ M* F- T6 H
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
( g6 _4 |& E: Y& w4 u4 `2 L &RecordsAffected,# {" D* Z; z L+ p4 X" A+ l2 X8 L
adCmdText);
7 o' d9 p, V. ~) `; C3 s! r) S8 } : n' j/ X7 [9 p' ^0 _
///往表格里面添加记录. t& P/ z/ m4 F7 m9 `
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);0 ]& Z: l/ @* v; W, s
, S( a/ [# I1 Y3 L2 z* Z
///将所有记录old字段的值加一6 i( }9 [* n. N3 z K6 J+ v
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
# H4 t' Q' m/ L( C
9 I3 i3 U! J: ]4 x% ?8 _ ///执行SQL统计命令得到包含记录条数的记录集7 ^4 R& }4 ]. X3 e
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);" q- e( c y) c' C1 i7 D
_variant_t vIndex = (long)0;1 I3 e' L1 y+ P+ i3 ?! X
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量! n m7 M, ], T6 @2 k
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));1 t- _2 U$ m' u
m_pRecordset->Close();///关闭记录集: E3 E1 w3 F* n3 m6 E" o" O& d+ G
CString message;2 u1 b& u' i0 W' i0 `- b3 C
message.format("共有%d条记录",vCount.lVal);$ U4 w" z' O! h( W8 ?* a
AfxMessageBox(message);///显示当前记录条数/ n" o; ^ N9 j
: R- C6 y1 p6 B2 ]1 L0 r7 _
(2)利用Command对象来执行SQL命令 % d# a0 T4 p; r9 a4 L$ s
" w& i/ H( _- t _CommandPtr m_pCommand;
$ Y K0 S% k+ ?! ^, l! z$ _$ f: w- M; ^ m_pCommand.CreateInstance("ADODB.Command");
+ x* L* K8 Q! |1 H% a _variant_t vNULL;2 A' y; _. a. P
vNULL.vt = VT_ERROR;. e$ d$ @4 n$ l9 ^( ]
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
B M7 _9 S; h* ?& _* ]- F m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它 R; S. d& g, @+ ]3 B1 h
m_pCommand->CommandText = "SELECT * FROM users";///命令字串
6 J8 r: r; p3 w" D1 Y. Q m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集! T2 v5 g. o# m) F B) b
5 P6 A5 c' c- Q! y% k3 C 在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
! ~( C2 [* I( A' P: O& _* `% B ' z$ V# o/ N0 y4 P: `3 v0 K
(3)直接用Recordset对象进行查询取得记录集( f3 h1 j+ u& U1 }. @
; ^ Y9 }3 o7 m# @" f
实例—— - c1 w+ J* i, [7 z7 e
8 G9 H8 A/ p+ i( S
void CGmsaDlg::OnDBSelect()
5 [3 u/ M/ B& M {
# P' C( Z- z# P // TOD Add your control notification handler code here/ i8 s1 w# o* C
_RecordsetPtr Rs1; //定义Recordset对象' i0 e. b; S- N8 C+ t2 @$ f0 ]
_bstr_t Connect("DSN=GMS;UID=sa WD=;");//定义连接字符串
4 C* r) P1 `- U% Y _bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
' }, g! t; `1 J ::CoInitialize(NULL); //初始化Rs1对象
9 z0 m. Y7 ?+ t: E; m2 } HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );+ e6 M( H- w+ ]* K7 y
//省略对返回值hr的判断 7 @7 W" E, [; S) J! T& D
Rs1->Open( Source,
8 q5 H1 n5 j/ @1 D" z0 e! ?3 } Connect,1 E2 C' y1 w# \) q. z: w
adOpenForwardOnly,
( P7 H$ n) _" | q' r6 l, N adLockReadOnly,
! m; d- C3 p: W$ y4 N. b -1 );
# `3 M* y" _3 U, x# i3 E+ { _variant_t temp=Rs1->GetCollect(_variant_t((long)0));
: k7 S, N- A: ~* T0 q, i CString strTemp=(char* )(_bstr_t)temp;
( ?! P( G9 f* F MessageBox("OK!"+strTemp);
' B3 x. [% ?/ d }
; T, b: p- T, Q4 S' [# D8 g ( ^# M9 [$ K& ^/ ]! F2 ?
例如 7 m# E* Z7 P. H9 ]+ X! g
m_pRecordset->Open("SELECT * FROM users",3 S: w/ t. [; K' y
_variant_t((IDispatch *)m_pConnection,true),) V; n+ n3 F. c" W" C2 J$ T
adOpenStatic,
$ }! G5 Z8 ^2 B3 g! H1 J _ adLockOptimistic,
6 g* I% C2 Q7 x: Y! B7 m+ q' y( k adCmdText);5 h4 ?6 h9 Z2 j5 A5 Q, j4 B, k
3 R) t$ j- j+ ~! J Open方法的原型是这样的:
8 R& p1 P' _5 f P8 { HRESULT Recordset15::Open ( const _variant_t & Source, # O3 |& G' j. X: j
const _variant_t & ActiveConnection, / f" j) Y* Z- S& @7 | v0 H
enum CursorTypeEnum CursorType,
8 |/ j4 }: ]2 O9 c/ x, v- {+ } enum LockTypeEnum LockType,
" ]4 F/ h: O* ~+ ?+ u long Options ) ; m/ H+ r8 g, i4 E- K; y4 P$ ?( @
" l' p1 `% s- p$ \; m
其中:+ P; r; J' X4 D2 b5 ^. k/ m
- e9 Q. X! o |" p ①Source是数据查询字符串( S( L8 J/ q) O" R2 A
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
* N. l6 z1 M1 ~0 C ③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:! b" J+ Z. N o0 [1 R0 m
7 B/ Q7 |) k4 X: W# h enum CursorTypeEnum
7 P0 {: |7 W3 b5 V/ V* U; \8 ] {$ m- Z; \: c8 c+ t, s4 H2 q
adOpenUnspecified = -1,///不作特别指定
$ ]4 I2 f% I s! x/ T; |+ W adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
5 y @' X' v0 I: _* |2 I adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。8 k# r9 w- ]: r" e* N
/ k& T: M" d9 I; ]; ^
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。6 {6 }3 N' W( I2 y
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。+ W, d4 l9 {9 b5 U3 i! \" x X
};2 J/ s' A9 T0 C% T: x# u
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:/ Q# I/ R6 F4 l* H5 f
' P& h" f# [8 v+ \* @
enum LockTypeEnum7 Y2 r T/ N p4 U: N
{7 W+ ?4 `+ _8 h e+ G. x% H
adLockUnspecified = -1,///未指定) i. w6 o7 T3 V4 C
adLockReadOnly = 1,///只读记录集) J0 H7 o! \) D# H0 D2 A
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制; {4 O" ~+ } [: m. |% y
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
: @% L+ y- S3 y adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。3 Q, {' k. O1 E0 ^- L" |$ G' K
};
/ w9 o% m* ~( ]2 T. |% T
# Y" R3 V/ R& z! ?, r8 p ⑤Options可以取如下值之一:
L6 g+ g: N1 g0 X adCmdText:表明CommandText是文本命令
7 G# f! K9 Z" R# G% N adCmdTable:表明CommandText是一个表名! k# x9 O9 p3 O3 b u ^ `
adCmdProc:表明CommandText是一个存储过程
6 Y6 o9 i5 M0 O5 [3 R( {+ | adCmdUnknown:未知
zan