QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3493|回复: 0
打印 上一主题 下一主题

[转帖]在Visual C++中用ADO进行数据库编程(中)

[复制链接]
字体大小: 正常 放大
god        

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集9 _) g2 E& T  L3 o

- U( ?$ \/ r8 X" O( `2 H$ P+ a  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
, L1 ]! J7 u/ E并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");* G: C; E7 h, P6 t, r' I$ x
SQL命令的执行可以采用多种形式,下面我们一进行阐述。; \0 E9 C) J+ K6 i6 c; }9 c

* B* C  O: L& ^) x# z% f: f( q  (1)利用Connection对象的Execute方法执行SQL命令9 ?4 l$ K' {& b" R# b5 _' R+ N
+ |; }  J2 @$ ~5 r
  Execute方法的原型如下所示:
1 ~. I: `5 T/ \% [, x7 ^, y/ P/ M" j
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) " p' u! n% T! t! B5 `' z+ s
! b/ _# f& M  a  e2 N4 p
其中CommandText是命令字串,通常是SQL命令。
# K! w! z& o0 w3 t) b8 t+ z参数RecordsAffected是操作完成后所影响的行数,
7 c6 X2 V0 M8 `$ y4 [. g/ v参数Options表示CommandText中内容的类型,Options可以取如下值之一:) {& p9 m- t. Q. C2 V' e3 n
adCmdText:表明CommandText是文本命令
/ G% A" {" E) @- U' w: L* _. fadCmdTable:表明CommandText是一个表名5 A2 j& l/ i. Q0 V4 X
adCmdProc:表明CommandText是一个存储过程+ H' m% G1 h0 X5 h3 N$ Y# y& z; o+ `, K
adCmdUnknown:未知
# d0 B. f: |) p( k) i2 Z; F+ E
8 }7 o( h. f, P* T: @6 T  LExecute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。 ! D" c; P- b2 q4 d, ], R4 R6 Y- b5 d
_variant_t RecordsAffected;" ]3 ^( U0 d6 ~' E  d
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday4 V" n! G6 W5 {- T& y
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
8 i$ t- y2 L/ z3 f&RecordsAffected,
5 Y  U1 Z$ |) ^$ d+ V8 r5 AadCmdText);0 y! b( |& R' `+ Q" p
: [( U$ ^, V. ]% O
///往表格里面添加记录
1 |1 i7 S+ C  \7 |m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);& U7 |& M, O: a! d( i
6 w- u/ e3 V5 B# y% o) J; K
///将所有记录old字段的值加一
1 S2 C  V( Q/ F. j; nm_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
3 }6 T; O! v2 X5 {* w2 ~( T  T% u# q! _' }. g/ ~
///执行SQL统计命令得到包含记录条数的记录集$ d# Z: t7 }" D9 i" s
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);3 R7 l2 P% t3 }5 n
_variant_t vIndex = (long)0;
% G$ V4 k. S+ F8 Q_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量5 V& Y( n$ F0 b
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
9 U3 i; R! X4 @# o. |7 v- cm_pRecordset->Close();///关闭记录集0 ]. n# v: j0 x  i8 g# _
CString message;) L  H2 w5 n4 P0 f
message.format("共有%d条记录",vCount.lVal);
7 U7 X" q0 x( h. c! V* YAfxMessageBox(message);///显示当前记录条数
" w( H* B3 B! u# S9 D7 C- v6 B) [+ Y; g# t0 x# p/ b
(2)利用Command对象来执行SQL命令
/ Z% \: n  y' f. G. ^' e7 _4 W) h0 J5 F8 \; t
_CommandPtr m_pCommand;
2 j( u8 Q/ l2 c& ^# K( d. xm_pCommand.CreateInstance("ADODB.Command");
5 z2 Z& ^, K' i2 g' {* ~_variant_t vNULL;
  _0 g: }; r$ m; hvNULL.vt = VT_ERROR;
& X- P9 P& M9 UvNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
$ v# F: _8 f1 `9 f+ n) [m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
- x2 k! a3 q" ^" A; vm_pCommand->CommandText = "SELECT * FROM users";///命令字串! H+ t$ f3 r) ~: n$ u8 f
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集( y2 v( i7 L0 }* l6 m5 B
: c5 l" X5 H6 ~7 q7 p1 a1 ~' {: C* {1 b
  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。 : A1 X  {7 A  [

* h+ g( u1 }" W) u- T8 Q4 |  (3)直接用Recordset对象进行查询取得记录集% k6 _& w/ ]4 ?: _( z$ J9 I$ D. y

, H3 ~" I& m, V0 c& y  实例—— 0 A- `; A+ q, T3 g* p
1 g! T. I; f, V% m) }; c
void CGmsaDlg::OnDBSelect()
" y1 {: J" G  E) r2 t; Z) f{
6 r8 X7 Q5 P; }8 Z  l1 {+ g/ ?  f// TOD Add your control notification handler code here
6 k0 K- X) L9 u3 ~0 `_RecordsetPtr Rs1; //定义Recordset对象
2 }' h7 S, U9 x) B/ ?1 Y0 W- |_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串7 ^, }) d+ s& w2 s: G5 D* f% X
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句5 a7 t& A; o; B8 M2 v) b" H" m  I
::CoInitialize(NULL); //初始化Rs1对象$ J$ j  v' D% \" V- X
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
  b+ k) ~, D0 J1 q//省略对返回值hr的判断
2 p* J, n" D4 ?- _5 N0 w, L# ARs1->Open( Source,
7 b) x& }# ~0 e+ H5 P# vConnect,% U- u2 Y1 y1 R) D, p- x7 K
adOpenForwardOnly,
: S' c# |6 [- d9 s5 NadLockReadOnly,# G8 E2 D3 _6 z4 o
-1 );
$ D( g+ t0 Y4 v2 O& S2 O* P_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
" P& o8 A& M( d( YCString strTemp=(char* )(_bstr_t)temp;. A  |. j0 w+ u8 f( |
MessageBox("OK!"+strTemp);
9 j0 J! c. x, Y( j/ l' U}
% _5 F8 K9 g& ^1 ?: Q0 N+ g/ k1 i; Y) m0 X3 o- j9 i  k
例如
' s9 X- a- H7 i+ Hm_pRecordset->Open("SELECT * FROM users",3 ]' k& X8 z& _0 ~
_variant_t((IDispatch *)m_pConnection,true),6 b7 _' W7 s& z6 B4 j
adOpenStatic,8 L1 E. W9 p) }
adLockOptimistic,) ], w- R- a7 ?. @3 Z) ^
adCmdText);
/ ~7 c3 r' Y5 P7 M' V/ A/ \% w
" E/ ]0 j" I6 v/ E. f8 E3 |0 TOpen方法的原型是这样的:
; V$ k# a  i: h! {5 h+ RHRESULT Recordset15::Open ( const _variant_t & Source,
3 G# I7 v/ o& q, ?const _variant_t & ActiveConnection, . b/ Y8 B: O: ^9 H! T5 ^7 B( Y+ j
enum CursorTypeEnum CursorType,
- ]" i: [; [1 Henum LockTypeEnum LockType,
- g4 n0 h# [) U/ }9 W: \long Options ) / i( J2 ]8 }  [1 B/ P$ O. b+ w% ^% v
$ G% r) E, r) K- Y# T) K
其中:) v7 x$ c6 v3 R, K3 b0 Y- z9 j
7 E- Z& |8 P8 R4 N& [  J! K
①Source是数据查询字符串1 P8 q- v  }+ l! Y
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
( A" R+ l5 v9 k! G③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
1 l# D5 }" T8 W0 H+ ]5 Z
4 e8 M' Q. m, {. v# i4 kenum CursorTypeEnum% V) ?* _) ~  X: {# a  e
{
, _/ R( W3 R7 k) qadOpenUnspecified = -1,///不作特别指定& W+ w- z' W3 B- m; E: J% p/ J/ f
adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
" r+ r9 i6 \4 Q5 y) `* zadOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
, D) p- V1 b5 d; m
, N9 G: t+ W5 ^6 @adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。, W' m# r# `$ ]: k8 p, X6 f
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。* i, h$ h7 c' m; F5 f" G9 i
};: I3 e, J/ S. u3 D7 Q6 q( ]# Z
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:2 c- ]* r7 h( ?  W8 g3 B

5 @+ K  H. c1 f+ Q# P/ tenum LockTypeEnum
* a& D6 C6 Z/ w2 [' p{
4 w5 F  e4 j- @3 U/ XadLockUnspecified = -1,///未指定4 K* s" F) _+ q& Z  |
adLockReadOnly = 1,///只读记录集- I  l  n/ x3 e; y$ Y9 R1 ~7 C% [
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制7 _0 I6 M+ e0 k6 P8 |$ z* W" @
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作# Y. w; y4 p" e! X3 y8 C& A1 y( V
adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
. X0 \4 B& [. I; K6 [}; + C9 m/ _& ]/ F% ~7 d: |1 ?. D8 ]% P3 `% d
' p% N6 C0 j, H
⑤Options可以取如下值之一:
, q1 \1 ^- j/ JadCmdText:表明CommandText是文本命令
: c% H0 f" F  W# |- k& s% uadCmdTable:表明CommandText是一个表名
9 `+ S0 D8 {$ ^2 F0 [4 z  I3 d, EadCmdProc:表明CommandText是一个存储过程
# c8 @6 m& O2 k7 l2 B2 sadCmdUnknown:未知
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
如果我没给你翅膀,你要学会用理想去飞翔!!!
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-4-17 00:02 , Processed in 0.409571 second(s), 51 queries .

回顶部