数学建模社区-数学中国
标题:
[转帖]在Visual C++中用ADO进行数据库编程(中)
[打印本页]
作者:
god
时间:
2005-3-30 22:53
标题:
[转帖]在Visual C++中用ADO进行数据库编程(中)
4.执行SQL命令并取得结果记录集
" d/ l, }1 z- D! z
3 }; l( b; I8 t+ m
为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
8 z3 v8 q8 ~) S+ e
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
& V0 J/ S% R! r- A3 e) O2 H: D+ }( A
SQL命令的执行可以采用多种形式,下面我们一进行阐述。
& P! p% n" d4 b$ X; `6 v$ j7 J0 u
! y! y7 X2 l5 F+ ~) ` |
(1)利用Connection对象的Execute方法执行SQL命令
0 }) R' {8 u* G* g4 F0 a) Z3 M6 m
) X6 R: L5 _/ T7 [% T% r
Execute方法的原型如下所示:
. m+ B7 ~ Y2 p+ l1 J
' S6 F6 O7 s2 W/ C( k; d% M
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
( ^6 Y& m% x) j7 P& U. g
" l, S/ P3 d, Y! e
其中CommandText是命令字串,通常是SQL命令。
: g1 A: F5 q, W; {) M
参数RecordsAffected是操作完成后所影响的行数,
* ?; t* T$ F3 r T
参数Options表示CommandText中内容的类型,Options可以取如下值之一:
! A4 m1 ~& g. L3 \/ v
adCmdText:表明CommandText是文本命令
6 e* p1 `1 g/ ^# Y$ A
adCmdTable:表明CommandText是一个表名
# D$ G1 }3 D( _$ k% ]2 D4 o
adCmdProc:表明CommandText是一个存储过程
2 c( T% Z4 ^- M
adCmdUnknown:未知
( e5 s: z" {6 ~; k1 y* Q
2 K3 I, |! j; u: r9 y& d! Y
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
6 X5 W4 u1 s) |
_variant_t RecordsAffected;
6 ^1 c# q2 t3 T
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
+ v2 ~+ E# [$ B/ K
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
9 p$ \1 p" f& |- h) ^
&RecordsAffected,
6 z7 d, f: W5 _5 j
adCmdText);
5 O- ]1 A- I% t/ B4 v& Z8 F
! S) u& `& F* s9 I8 F, \
///往表格里面添加记录
w& p0 @' \ m1 [4 {0 E
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
+ K) @# {' o+ R( B+ y5 x, a+ S
% w! b- @* A, t. Z$ l5 }. k$ y# C! J8 S7 a
///将所有记录old字段的值加一
) L0 D- ~/ V, { O
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
" g/ ?/ J/ ]4 I* F9 y
. z0 J, F) W' J# O
///执行SQL统计命令得到包含记录条数的记录集
# V. |! y4 Q% h5 s% D* Y* r3 e
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
" K; X, c6 q1 T
_variant_t vIndex = (long)0;
" p' Y) ^4 d- V2 X0 ~ M
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量
) t: Y( {% D$ }% ^4 ]. w# f
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
8 O* N7 V2 n% G, n" P. r4 I8 d
m_pRecordset->Close();///关闭记录集
5 R& {9 r9 |. r7 @" R
CString message;
' ]. F4 L, a6 I$ h9 }, C
message.format("共有%d条记录",vCount.lVal);
7 Y' n" o5 s% i9 f3 T3 n2 K
AfxMessageBox(message);///显示当前记录条数
9 Z& W" c) ~+ Y& U9 F4 k! I x }, f
; p7 R% q. _* s' S1 Z9 W
(2)利用Command对象来执行SQL命令
$ U {: o5 G8 {5 u$ G$ L+ X
" q" Q8 V+ V: m0 L ^3 T
_CommandPtr m_pCommand;
( ?% S. H! c8 ~+ p6 G: j, q
m_pCommand.CreateInstance("ADODB.Command");
- w, S2 Q) u' K, O$ `, U
_variant_t vNULL;
+ x) e/ \ }* q! Y2 G) b$ J4 P0 C
vNULL.vt = VT_ERROR;
5 I! `9 z3 L+ r+ q; a
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
( n- I4 l# E1 x2 e
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
! ]8 U' j5 {, c9 O5 u
m_pCommand->CommandText = "SELECT * FROM users";///命令字串
p8 n- a# m) e4 j
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
/ h& _1 x9 R: a3 L5 \6 N! w: u
+ M5 X4 e8 F* g
在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
9 @6 ~; ~- r$ j' L( F
7 F% y6 {# i3 Y% G4 z
(3)直接用Recordset对象进行查询取得记录集
2 K6 t1 J. U5 t# V* U; q3 i1 D) O
# a8 K2 t3 D) j- w5 W
实例——
8 K1 S: b7 ?6 Q# ~8 }
- K& h+ _( t0 m4 H+ `' V; S
void CGmsaDlg::OnDBSelect()
. i1 n6 f o0 W
{
9 A! z8 d4 Z2 l8 S a7 v& t
// TOD Add your control notification handler code here
% P; d0 _" q7 M
_RecordsetPtr Rs1; //定义Recordset对象
) {- X- A7 Y0 t; b9 D/ m0 l
_bstr_t Connect("DSN=GMS;UID=sa
WD=;");//定义连接字符串
! n/ j( A$ j, o1 q3 _
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
- \' o! F$ u& R
::CoInitialize(NULL); //初始化Rs1对象
1 k$ O6 l( N9 J9 i) H* }
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
9 e) c7 K! S, `; O" b: p% \
//省略对返回值hr的判断
* u) ?& F2 q" B
Rs1->Open( Source,
1 P1 r _, d0 G; J7 d' q
Connect,
; v/ I% Q- T4 @" E9 Y, y& p
adOpenForwardOnly,
0 M) n6 h3 q: x
adLockReadOnly,
" A2 m" s7 c8 n" p' j
-1 );
" @5 Y4 }6 y1 `! V
_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
) D& i0 t5 y! L/ ^
CString strTemp=(char* )(_bstr_t)temp;
! ^% n. X# O& p! @
MessageBox("OK!"+strTemp);
% X) ^, Q$ h7 o! Y" D3 ?) F2 m
}
7 ~2 L1 I1 i0 ]$ x/ @! J
2 X& x8 R5 y+ y7 w" ]! a+ _3 z3 {
例如
' E, f) N% H* S1 e! e6 W6 h
m_pRecordset->Open("SELECT * FROM users",
+ y4 s% k( U3 ^# w
_variant_t((IDispatch *)m_pConnection,true),
' F/ z- I/ T; ^1 w% K4 Z
adOpenStatic,
7 q: T+ n, S, }2 g! L: f$ _9 i/ m
adLockOptimistic,
" Q. h' u$ f* i# l) b; g I
adCmdText);
, }" V: y2 M' b6 M- w& `( u! X
( P. R4 Z# M# a7 c% f% {4 v
Open方法的原型是这样的:
- j/ r; s2 \: J0 u$ ?
HRESULT Recordset15::Open ( const _variant_t & Source,
$ {; L/ |5 j) X$ T* K9 |! a
const _variant_t & ActiveConnection,
0 Z8 ]* O5 [+ h& v$ J; e r
enum CursorTypeEnum CursorType,
; @8 j7 k' _! E
enum LockTypeEnum LockType,
6 O! [6 ^5 Y8 C: O1 A
long Options )
! H4 L8 Z& g+ ^6 a& B4 c
" S y3 u, w ^2 c
其中:
8 k. v" \. B- O+ L' |' l' B
4 m1 S' A) v( U
①Source是数据查询字符串
3 A) i R1 _, `2 W( G0 A
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
. ?; j0 ?0 ]! f/ u. Q
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
7 u4 x9 w6 H' n! w/ j/ F e0 H9 D
& _: k3 Y }5 n
enum CursorTypeEnum
1 s* d; P3 E# G
{
' M; S3 v* {- U! l! y5 J' _+ r
adOpenUnspecified = -1,///不作特别指定
, P# }: Z7 Z* u. N0 h- D6 s
adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
* |3 h, L9 [/ S4 Y: l
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
+ z8 A `1 ]/ t3 A
) @' f. S+ x% G, R$ W/ R7 a8 R
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
8 U" J( o3 f7 B1 Z9 t5 I) Y4 v; d
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
. \& {9 s: Y# i! n' {, Z
};
( ^+ z) A9 ^) P7 o1 H8 p" ~
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
" J6 V7 V& l) {
8 u* g, [+ P# @
enum LockTypeEnum
) ^# z! X1 q2 ~! F: t( x
{
+ E# V# c! {1 g3 c, X, t
adLockUnspecified = -1,///未指定
, T* w R% A! V* O0 \/ {
adLockReadOnly = 1,///只读记录集
Z6 Y% u% z3 H1 O* i2 h# q
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
8 d+ B; ~' D+ G5 r$ X* r
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
$ X( X& P7 |/ z. d; l
adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
. `5 Q; W6 T1 _% T0 b5 H# L& _& P
};
6 ~) N$ I; A4 @+ Y
; X/ U. Z5 V$ Q, Z
⑤Options可以取如下值之一:
c7 P9 | B" O" K
adCmdText:表明CommandText是文本命令
! [; R, P8 O w- [$ x+ d7 x
adCmdTable:表明CommandText是一个表名
2 O' Y1 }( z7 W% j
adCmdProc:表明CommandText是一个存储过程
8 ^! U! A. J3 Q7 g3 a4 \, c
adCmdUnknown:未知
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5