数学建模社区-数学中国
标题:
[转帖]在Visual C++中用ADO进行数据库编程(中)
[打印本页]
作者:
god
时间:
2005-3-30 22:53
标题:
[转帖]在Visual C++中用ADO进行数据库编程(中)
4.执行SQL命令并取得结果记录集
6 l( C# i; X4 n$ [/ D; P$ w
- M: R6 }0 z* [8 c/ `0 V i3 z
为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
. _* @; Z% S* A- n6 C5 A; ~# J
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
' Y: F& B, C1 ~5 Z! E `
SQL命令的执行可以采用多种形式,下面我们一进行阐述。
3 b' A f+ T$ Q. f
& X) {1 ^( A8 V: [1 Y' C: |( {
(1)利用Connection对象的Execute方法执行SQL命令
# A; G2 H O( R7 I
' ]( N* `% Z$ m5 c
Execute方法的原型如下所示:
+ ]1 |0 m- U+ G
+ F( s3 i6 V8 m- q- z+ @
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
& Y4 n$ s, X9 M5 d% b* B+ y
, G( | t* D: N6 _' s6 R/ Y5 O. o
其中CommandText是命令字串,通常是SQL命令。
) u" }. n+ [$ W( f
参数RecordsAffected是操作完成后所影响的行数,
8 e! j2 u K8 S, S' d
参数Options表示CommandText中内容的类型,Options可以取如下值之一:
* c0 _; s! k* G: m: h3 M4 L& e
adCmdText:表明CommandText是文本命令
9 X1 T+ S' ? W: f( k
adCmdTable:表明CommandText是一个表名
/ Q5 J2 _1 w% E! V! u j
adCmdProc:表明CommandText是一个存储过程
g4 _/ {. f: W
adCmdUnknown:未知
! T# G8 x3 K4 z0 B$ a2 [
1 U |% J: |+ I1 d, I( a
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
; K5 `" q3 e- _ W& b. i
_variant_t RecordsAffected;
" B( N! F/ l7 E% _% u, s
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
5 e* `* w1 u6 K. S- E, O
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
) }# q) y4 R7 L, V/ V& b
&RecordsAffected,
' C, @) R! O5 ]" [; K7 B/ e9 ^& x
adCmdText);
; N: {) X: C1 \: `6 P% Y5 C
9 T% o+ b; c! c+ S; c( e( G |- a
///往表格里面添加记录
: y4 x( K& N% P6 w
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
r3 J0 u O# C- P' m
% N9 }. s- l! l/ P( U
///将所有记录old字段的值加一
7 b& g& @" _- k. n1 W/ x" [! a+ k
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
" z+ \9 y" h! q& s; T& P+ F
+ w8 C0 V; d- z1 i# v" p
///执行SQL统计命令得到包含记录条数的记录集
0 H, W, ~7 { `+ }) g4 d
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
* J( N% s6 ~8 J# Y O0 N) z/ U
_variant_t vIndex = (long)0;
' |* U [) Y7 c, o+ H+ X, M3 H
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量
/ p, m$ R) Z: W l7 ~1 o
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
! K- t# s# ?7 h
m_pRecordset->Close();///关闭记录集
6 u* ]6 F0 W L2 p- I
CString message;
; L- p2 a, a9 d; m; U" C
message.format("共有%d条记录",vCount.lVal);
- c L/ h9 Y/ _1 r& g k: C
AfxMessageBox(message);///显示当前记录条数
1 `$ b1 M* _: \
( R6 p( g' m& ?+ m0 M% `
(2)利用Command对象来执行SQL命令
7 G e* l, ^. @0 z" }- r" R
- d9 d# m' s& j: M9 O7 O3 g0 L& l, @' h
_CommandPtr m_pCommand;
- w# l0 l" w, y/ [1 R
m_pCommand.CreateInstance("ADODB.Command");
! [: W& J: N1 I& k/ g
_variant_t vNULL;
- g. J! u4 |) m) V
vNULL.vt = VT_ERROR;
i8 O+ n- v% {' B) D' }0 o
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
2 r6 S n9 M( I' d
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
3 E2 u2 u M1 Y; O9 O' ^& ~2 Q) T9 y! d
m_pCommand->CommandText = "SELECT * FROM users";///命令字串
& Y' K( o( |% F
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
/ z% a7 [0 O, A: P; n7 u
: m7 D4 E& z: F6 z$ ^
在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
9 B# z; }9 R0 o. _' M
" q: z+ Y* M& C% o9 j4 i! V
(3)直接用Recordset对象进行查询取得记录集
. D3 _1 c) R, ^3 e$ E- F' A
3 L. k+ l" X8 M9 T2 L( S
实例——
9 e, h% u& {) W) I6 a; ?
. I! N& _/ @+ B' w9 @3 o) m
void CGmsaDlg::OnDBSelect()
7 H, ~9 q( C2 b5 g7 v3 y9 X6 e
{
3 E7 i: G5 J2 ?8 F+ }$ E
// TOD Add your control notification handler code here
8 U8 z9 W6 o& w5 t" K& i8 \( h3 j2 o
_RecordsetPtr Rs1; //定义Recordset对象
4 u- g# G# o5 n0 J
_bstr_t Connect("DSN=GMS;UID=sa
WD=;");//定义连接字符串
; c+ b. ^1 W$ W, A
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
, C4 K z% k+ n3 D5 S
::CoInitialize(NULL); //初始化Rs1对象
$ b! o! t5 p) S- v! N3 m) f2 i
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
& S1 W& o# `6 r% Y4 e' {) C7 N
//省略对返回值hr的判断
2 m( I1 H* {" I6 q, r& ~$ W3 u
Rs1->Open( Source,
2 y \2 D5 N5 [+ i( Z$ h8 C
Connect,
" L j! d7 g- Q9 C
adOpenForwardOnly,
' w. t6 w! V c6 k4 O+ q
adLockReadOnly,
/ T* m n3 j F$ {5 J, s0 ]6 ^: v
-1 );
" [8 b# ^6 I& ]# m7 r6 j
_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
% k* p7 l6 C" O, N( _8 r* s! L0 R
CString strTemp=(char* )(_bstr_t)temp;
; f& q. w+ e9 i; R! D+ T
MessageBox("OK!"+strTemp);
1 b4 w; R) r) C
}
0 Y% z1 a+ z9 w
2 h$ j7 t, n* ?3 b _
例如
- X) d) n. g- |7 W* E
m_pRecordset->Open("SELECT * FROM users",
( i0 {1 `" R7 q5 v6 ^# b
_variant_t((IDispatch *)m_pConnection,true),
; h+ i6 _! G0 X3 Z2 A
adOpenStatic,
, {8 D" N: `/ H5 \$ r% ]
adLockOptimistic,
: t- L' ~! a4 R1 Y/ r
adCmdText);
6 c5 \7 |7 X* e# h- o5 F. ]3 L
% k, h0 z# y% M Y9 i
Open方法的原型是这样的:
4 y4 M6 u; c. e2 j0 z8 l
HRESULT Recordset15::Open ( const _variant_t & Source,
4 {! Y+ J$ D5 Q
const _variant_t & ActiveConnection,
& w& c# V7 U4 I( U8 g- c+ f
enum CursorTypeEnum CursorType,
* e# X9 H+ ~$ ~+ k0 g
enum LockTypeEnum LockType,
0 V8 g) |# O/ V! J5 L
long Options )
3 \& h3 O0 d! d2 B8 O/ t
" J1 U" E* P: w& ]$ i! O+ ?
其中:
5 e( ]! J' n2 U5 Y5 N& h) w2 Z
4 e7 D7 T: \) J: B
①Source是数据查询字符串
! \* x2 b( e- o, I6 x& G# Z% x
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
" Z# b2 c3 B7 _0 ^
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
- V. @/ O: @, h# \
! ~ z9 K6 K0 _1 Z3 I* ^
enum CursorTypeEnum
& P: \9 H: l; Q( i# a
{
! d/ H3 u1 ~) [' s# a
adOpenUnspecified = -1,///不作特别指定
+ u! a: b1 d: {+ Y7 w
adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
8 X1 Z, O j+ B! E, _0 P) E: p
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
3 ]5 J7 }# s4 Z- D& x7 ~- W
9 Z; b, I4 g1 q
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
; Z! w& P+ e& l+ S4 Q8 [- I
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
! J( A# `0 f4 F+ q& d* n
};
5 g' I- K! Z9 U: u" ]5 u* G
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
' L Z9 |: h, s
! i$ M4 p' X! Y. B
enum LockTypeEnum
9 _* u$ y( \2 O; e; H
{
5 v8 O2 Q% r" C4 E$ U/ A4 C
adLockUnspecified = -1,///未指定
: g5 D5 C* t/ C& w5 }4 R' B$ e3 e4 [
adLockReadOnly = 1,///只读记录集
V6 ?3 D% i- n' R$ [3 @6 E( a7 ?
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
# U: W. Q* `: l1 Y9 e0 d
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
9 E' f, C! p# q/ q c' x
adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
- R5 p s# b. Y
};
. `" ~" Y6 s/ A
- ^' L8 I4 O' o7 P
⑤Options可以取如下值之一:
) ^ O& C5 F. m+ D3 b
adCmdText:表明CommandText是文本命令
I8 s* ]2 V- G& G% o9 J& \- P
adCmdTable:表明CommandText是一个表名
0 R2 a7 D! B& J) _ e
adCmdProc:表明CommandText是一个存储过程
3 W5 u, u. ?2 B; {2 j& K% p1 a# g
adCmdUnknown:未知
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5