数学建模社区-数学中国

标题: [转帖]在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 dSQL命令的执行可以采用多种形式,下面我们一进行阐述。; 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* RadCmdUnknown:未知/ 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# nm_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 ZadCmdText);
3 Z( L6 C4 L/ E  c
6 M3 E. Z0 g' t+ w0 k///往表格里面添加记录
- L) N9 @8 P1 Dm_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
; T6 }1 R! _6 z% g+ L4 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( um_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 ECString 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 U1 {. _8 q- }: L4 x
_CommandPtr m_pCommand;
& b, w3 l5 |  t- f1 ym_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 XvNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
0 d7 }- ?7 \# b2 u3 ^0 Om_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
  J: K! _  u/ e9 g, \. r+ Fm_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 Qvoid 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=saWD=;");//定义连接字符串, 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' cRs1->Open( Source,
9 @: c, F# \6 o6 f/ Y# W+ L* OConnect,  @( W- \: s) P; O) ~3 V
adOpenForwardOnly,
: ^4 ~- g+ o2 q0 k3 X* ?# iadLockReadOnly," [  @+ 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: gCString 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( Cm_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, yadLockOptimistic,, 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 FOpen方法的原型是这样的:
; D, |, D9 N5 c/ WHRESULT Recordset15::Open ( const _variant_t & Source,
3 A, A  H- m/ P  x- t0 C$ Y/ Gconst _variant_t & ActiveConnection,
6 ?3 {4 U/ z& u# P( D0 x" Genum CursorTypeEnum CursorType,
( L& R3 N+ B6 s0 x$ d& N- Penum 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 aadOpenUnspecified = -1,///不作特别指定
  x% r: B* P4 X5 j, {; ~0 \- Z8 BadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
6 Q; H) D3 a' eadOpenKeyset = 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 QadLockUnspecified = -1,///未指定
" ^) V' D, D4 n5 a, S' s% ]1 `0 ]2 M- fadLockReadOnly = 1,///只读记录集
3 U0 V/ F& U1 ?/ g9 qadLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
  e$ u$ y" S+ _6 n0 ]( ~3 [adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
- }1 \4 J: k* h3 W, }2 EadLockBatchOptimistic = 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% padCmdText:表明CommandText是文本命令# x- _4 D2 h( y$ I1 U& G) J
adCmdTable:表明CommandText是一个表名
- @) p. Q0 d3 UadCmdProc:表明CommandText是一个存储过程
5 Q; J- [/ Y1 {# [( LadCmdUnknown:未知




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5