数学建模社区-数学中国
标题:
[转帖]在Visual C++中用ADO进行数据库编程(中)
[打印本页]
作者:
god
时间:
2005-3-30 22:53
标题:
[转帖]在Visual C++中用ADO进行数据库编程(中)
4.执行SQL命令并取得结果记录集
9 {$ d4 P" y6 x. E+ Z7 S( s
4 b' z1 T; T( V/ s
为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
! g: M6 u! }9 @
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
: y) h9 m+ O1 [0 d
SQL命令的执行可以采用多种形式,下面我们一进行阐述。
; Q4 _3 ^6 R' e
; a4 _3 l. _9 I j' U y
(1)利用Connection对象的Execute方法执行SQL命令
' _: j7 p2 e9 T' n; i
; o0 f2 s2 M F: o% h Q
Execute方法的原型如下所示:
2 \9 [1 ], T# J1 S' s# c
$ K9 t* J p, m# ]
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
* [4 P" Q1 A: D p- a- m4 y
) {, v6 _5 @# O6 e; W/ |" w5 |9 |
其中CommandText是命令字串,通常是SQL命令。
/ z& J Z t5 u+ q9 q/ J
参数RecordsAffected是操作完成后所影响的行数,
) l |% p" x# B9 Y
参数Options表示CommandText中内容的类型,Options可以取如下值之一:
" l3 H6 S& t; A$ {* W
adCmdText:表明CommandText是文本命令
! g- Q; n& L# E7 _: X% h* }4 y4 R
adCmdTable:表明CommandText是一个表名
! L5 m* D* q/ j
adCmdProc:表明CommandText是一个存储过程
8 u9 c6 W/ \) E! M3 ?2 O! i* R
adCmdUnknown:未知
/ H( @! I) h; f8 k/ r
' E, C4 S' {7 V; T6 k/ p% p9 z
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
/ }! O( F" Y' B! w4 V y" Y
_variant_t RecordsAffected;
7 E4 I+ C6 L/ K; e
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
# U( p+ u8 T/ `( _4 d4 u# n
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
' v+ l+ l1 m$ e/ N+ ]4 n1 a2 L0 y
&RecordsAffected,
! } H$ v7 T: F' ^ @1 Z
adCmdText);
3 Z( L6 C4 L/ E c
6 M3 E. Z0 g' t+ w0 k
///往表格里面添加记录
- L) N9 @8 P1 D
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
; T6 }1 R! _6 z% g+ L
4 i( V8 ]9 x4 |( S, e p9 q2 Z7 {4 @
///将所有记录old字段的值加一
. ]0 W2 R6 A% R. I, D$ H6 F( F% ]
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
O0 `: ?2 ~2 ?! B1 z
' v4 W. c; |, y
///执行SQL统计命令得到包含记录条数的记录集
( z: L8 ]3 R0 c7 f0 D3 f7 X( u
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
* C/ F; G/ l7 B( D- v
_variant_t vIndex = (long)0;
' E6 J- B6 m7 x; y; s, L4 [8 y
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量
% `: @; B5 e i. W* ?+ ^
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
$ X" [0 C4 c) t5 x2 h$ m
m_pRecordset->Close();///关闭记录集
8 Z' L+ {9 Z. {/ k7 `7 E
CString message;
% K4 x" M; Y: [% R2 p
message.format("共有%d条记录",vCount.lVal);
I7 |" W% p) X6 @1 @9 ]
AfxMessageBox(message);///显示当前记录条数
( S6 g, h/ V/ [% E4 ?% Z
`* r( ]+ G+ i; ]' W
(2)利用Command对象来执行SQL命令
' l( o3 t' w. }$ J9 \$ X( e7 U
1 {. _8 q- }: L4 x
_CommandPtr m_pCommand;
& b, w3 l5 | t- f1 y
m_pCommand.CreateInstance("ADODB.Command");
* W% j) E- u' z1 b
_variant_t vNULL;
3 T5 }' S6 Q6 J/ ^
vNULL.vt = VT_ERROR;
! T, {- L6 D1 X
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
0 d7 }- ?7 \# b2 u3 ^0 O
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
J: K! _ u/ e9 g, \. r+ F
m_pCommand->CommandText = "SELECT * FROM users";///命令字串
- i3 {. j4 D8 x( c* ]+ G3 P
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
5 r, y0 N% A, l6 m' a8 l
% n/ P+ |9 c2 p" \; h! f
在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
' l$ m- ~; q* [5 R% K7 K4 Y$ Q4 ~
; ~2 k' w& C( D! U1 i1 a9 L
(3)直接用Recordset对象进行查询取得记录集
2 L/ n5 t2 g* K+ @. ^+ c
. J; H% m7 ~' J
实例——
1 j8 r$ z/ l4 M- L2 Q
8 [8 n; l" j) T" Z6 Q
void CGmsaDlg::OnDBSelect()
4 O9 \1 g% u2 |
{
0 e5 V. o* t" @* I- v* z
// TOD Add your control notification handler code here
' D' l4 |; k7 b/ z) s
_RecordsetPtr Rs1; //定义Recordset对象
( e. u4 k, p, m! O% X
_bstr_t Connect("DSN=GMS;UID=sa
WD=;");//定义连接字符串
, P6 d2 j Y' k3 d% i! r, p
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
1 K- n& f$ P( s7 A/ y! ^
::CoInitialize(NULL); //初始化Rs1对象
& h& g$ _0 e' o- e2 b
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
, h* x8 c: l8 L ~) m0 p( Q+ v8 N
//省略对返回值hr的判断
- M9 {& y+ r' c
Rs1->Open( Source,
9 @: c, F# \6 o6 f/ Y# W+ L* O
Connect,
@( W- \: s) P; O) ~3 V
adOpenForwardOnly,
: ^4 ~- g+ o2 q0 k3 X* ?# i
adLockReadOnly,
" [ @+ C# z4 n5 R! s
-1 );
2 u7 f# I, D9 h1 [" }
_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
3 _* y m/ c+ z4 d4 s2 O7 F: g
CString strTemp=(char* )(_bstr_t)temp;
- u4 T4 Y) o- J( o' O
MessageBox("OK!"+strTemp);
Y) O: [! I# k7 x. \2 {
}
/ W$ h. a6 ^3 c: g- {" R, M2 |
8 Y7 h% r2 _' D1 y
例如
4 `% c2 {1 j/ Q* f( C
m_pRecordset->Open("SELECT * FROM users",
Z9 o! J9 w9 ]3 F$ a
_variant_t((IDispatch *)m_pConnection,true),
; i4 \) r. d' p) C% B2 I! A2 `; i: _
adOpenStatic,
3 T+ g+ Z- z9 n$ D4 R, y
adLockOptimistic,
, M& c5 a+ U2 p7 d- t# C# E4 c, q
adCmdText);
& D5 F# i* @; @! G/ j
0 v3 O' Y5 P) L' K% X5 d* V9 F
Open方法的原型是这样的:
; D, |, D9 N5 c/ W
HRESULT Recordset15::Open ( const _variant_t & Source,
3 A, A H- m/ P x- t0 C$ Y/ G
const _variant_t & ActiveConnection,
6 ?3 {4 U/ z& u# P( D0 x" G
enum CursorTypeEnum CursorType,
( L& R3 N+ B6 s0 x$ d& N- P
enum LockTypeEnum LockType,
2 V# Z2 A" M$ [8 ^0 p+ J
long Options )
+ @; F3 a+ g, d9 s" I6 L
4 }$ ~$ v$ j9 Q, x! m
其中:
Q7 a2 H/ \% D- M- k
- M7 n" s) q' r2 k7 M8 Z
①Source是数据查询字符串
& V6 Q/ u8 Y# Q8 O, [5 r
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
& j( R6 i p P: I/ ~8 m, M8 I) `
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
* n7 b W0 K3 P+ g ~2 O$ |
+ P5 E* y* ~/ C' N5 t+ r+ z. o
enum CursorTypeEnum
3 q N- q6 J' r# J8 `' d+ d
{
. L& J' [4 Q" k x5 a
adOpenUnspecified = -1,///不作特别指定
x% r: B* P4 X5 j, {; ~0 \- Z8 B
adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
6 Q; H) D3 a' e
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
. Q; _% B: t( Q' h' b. J
% a& q. f* N9 t' V6 l S, @
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
# S0 {# K/ ^+ k( J3 y9 ~) Q
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
" h" }, n% ^: n& Z, @' s& R: \. ?
};
, |* n. ?' v. z' ?4 L Y$ P
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
+ D$ T" b, Z3 u- j" u7 ~
$ e5 M& ?) Q# q3 E
enum LockTypeEnum
( m: T" M, j8 k4 G, D
{
' A8 y+ ^7 A* t4 {4 Q
adLockUnspecified = -1,///未指定
" ^) V' D, D4 n5 a, S' s% ]1 `0 ]2 M- f
adLockReadOnly = 1,///只读记录集
3 U0 V/ F& U1 ?/ g9 q
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
e$ u$ y" S+ _6 n0 ]( ~3 [
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
- }1 \4 J: k* h3 W, }2 E
adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
7 j3 i# ~' U, v( x' g" S8 h
};
: [$ Q. U/ _/ t! a- `2 Z; m7 K
" Y. z* D* a3 x, C+ c
⑤Options可以取如下值之一:
$ ?' Z6 C/ S3 `' G5 O% p
adCmdText:表明CommandText是文本命令
# x- _4 D2 h( y$ I1 U& G) J
adCmdTable:表明CommandText是一个表名
- @) p. Q0 d3 U
adCmdProc:表明CommandText是一个存储过程
5 Q; J- [/ Y1 {# [( L
adCmdUnknown:未知
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5