QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集1 t5 j- d/ H( U; y$ ^  g7 f
: M! M5 g4 B/ v3 [1 o( Q8 }4 o& K
  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;/ g9 G# |9 k# W1 z% X+ P  A
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");; {, A! g( B) M& s6 d
SQL命令的执行可以采用多种形式,下面我们一进行阐述。
+ H1 o+ A! E( m! Y- d
+ P  b& C; u- {! G. R  (1)利用Connection对象的Execute方法执行SQL命令
1 U2 G5 [* P6 k  H: X1 z1 s  L1 w+ F( o4 z& ^
  Execute方法的原型如下所示:' e3 P% J+ H- d" {+ h+ Y: `
. v  t5 q6 z# f+ x% i, x
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) & g/ }! _! b" j; z: B% T  J

$ [, b. U. k# ]8 R* q* `其中CommandText是命令字串,通常是SQL命令。! o+ _/ }! G& V) ]7 V' a
参数RecordsAffected是操作完成后所影响的行数,
) T0 z5 ]/ T7 e; ]/ @参数Options表示CommandText中内容的类型,Options可以取如下值之一:( K" s/ o2 D4 q, I' S4 I9 k* ^
adCmdText:表明CommandText是文本命令4 h* p& `! `) e: \( W+ k4 r( E
adCmdTable:表明CommandText是一个表名1 G$ k5 B1 Q1 H* w
adCmdProc:表明CommandText是一个存储过程3 L% w, K% o) R$ ?% _% F+ w  U
adCmdUnknown:未知
& I2 X) j( N' F+ @
9 k9 s. j" F0 o2 d) oExecute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
; S8 p' s8 ~- \0 Z1 O  O! l_variant_t RecordsAffected;" D: `9 L. H/ P; K
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday$ T! j/ k2 p9 ~( z) x; b
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",5 }- H  `9 t6 I
&RecordsAffected,
1 E6 E! j, F0 s4 \1 w+ badCmdText);' b- h3 i  c0 u
- d1 |5 X- v7 z9 ?" u9 }4 @+ ?
///往表格里面添加记录
% r# {6 e) \; s8 J. g& Vm_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
- P1 K; T$ M6 l) M
. X8 B) o9 f/ P! P1 T* _( w8 a/ x4 D///将所有记录old字段的值加一
! h& N9 b' Y& N) R% nm_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
! f2 a  u/ B# }0 c: c. M% {
, ~2 [" h0 k. |) \+ }///执行SQL统计命令得到包含记录条数的记录集7 T4 P" R$ s: @  ^& K$ M
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
. P8 d2 G. R) T) Z0 q. n3 h& t_variant_t vIndex = (long)0;
" G" W. P( U; C' C# I_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量% b( M( c5 _# T9 ?7 [6 O' B
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
9 n9 ~. t. E2 p1 d. }m_pRecordset->Close();///关闭记录集% A* ], I# B1 |/ m
CString message;
. V! d" M  x: Y+ ~message.format("共有%d条记录",vCount.lVal);. j+ O: Q) P5 O: |
AfxMessageBox(message);///显示当前记录条数
6 ~0 D6 _6 n/ p8 m* `+ B, T# [: o
- G2 z+ N  f* j9 V1 Y" [(2)利用Command对象来执行SQL命令 0 Q. X$ Q) o; K! {6 `4 g

" J2 U5 v/ w4 i4 h7 D' v_CommandPtr m_pCommand;
" e/ {, E3 ~! R& j/ hm_pCommand.CreateInstance("ADODB.Command");" m, |) b3 z" [4 F& H
_variant_t vNULL;  O. E: V) t6 |5 N. A! _; d
vNULL.vt = VT_ERROR;9 A( \& H9 H( t7 Y0 W; P; f& u
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数+ r' b0 N4 P& i9 K* g
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
! ]3 a& G+ w" {4 g# W( lm_pCommand->CommandText = "SELECT * FROM users";///命令字串
2 i' A2 K7 z: g3 j: _3 r- _m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
4 f  v8 R. Q7 {# T5 O  }
* C# A7 x4 h3 a/ i# L  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。 % F7 }- B1 c/ ]: h4 \

7 D5 B4 |* ?% y5 w# v  (3)直接用Recordset对象进行查询取得记录集
+ ^( B- Y. y: O" Z3 Q
& c. x2 o6 M) i; ~  A, r  实例—— & p* k2 ]5 b7 Q, l% u6 H
# x4 ^2 x" D, ?% a$ l/ e
void CGmsaDlg::OnDBSelect() * `* Z: G( t- q, l- x" H& ^) w
{
- k6 n8 p0 E( e+ k// TOD Add your control notification handler code here" I( r6 V% o& l* G9 x. L
_RecordsetPtr Rs1; //定义Recordset对象5 x" N8 _3 V9 U. w; x
_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串
$ |5 r: g/ G6 r1 x* J6 A_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句& T1 a+ u; w6 m: \  m9 _
::CoInitialize(NULL); //初始化Rs1对象0 y2 C% O: V. K6 o7 F' Y# Z6 U/ D+ g
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );0 w! x& I/ |/ k5 r  R! {
//省略对返回值hr的判断 , B! J* A9 U* y# i
Rs1->Open( Source,; p* o7 d# M8 R7 B
Connect,
, G5 `! `6 O$ v) K6 f; r) HadOpenForwardOnly,
8 Z! {: E" N) F, SadLockReadOnly,
# C# L3 i2 P- _' I/ A-1 );
1 f# C- `# E% M* N# F( @_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
3 X- u* z/ x6 ?CString strTemp=(char* )(_bstr_t)temp;* W: T; ]- H8 r8 `! T+ _5 p
MessageBox("OK!"+strTemp);  W% F% a; f4 k  V5 [, r
}7 A8 A) I, p6 n/ f

7 H7 C6 ]- x% f% {, ^  N- X0 B3 _/ O例如 . Z" Z: j4 O+ T- m
m_pRecordset->Open("SELECT * FROM users",
9 A% @: F4 r( l. L4 Y2 ^_variant_t((IDispatch *)m_pConnection,true),
. E$ o* z9 {2 H% ~+ I& `& ^) VadOpenStatic,; U, b1 }2 ^/ x& C' ]& |
adLockOptimistic,) m' m$ r) I) v% O* W4 N9 C, c
adCmdText);( Q" J5 h. a& [( `7 L! ]( R4 B

/ y0 Z' }$ p' D+ E4 L& e# YOpen方法的原型是这样的:
( m8 n8 p9 Y6 g- UHRESULT Recordset15::Open ( const _variant_t & Source,
+ c  }3 T1 }0 q& Y& l5 Pconst _variant_t & ActiveConnection, & P& ~+ v0 _. e6 A- y# [
enum CursorTypeEnum CursorType,
8 S8 N' t. U5 N" H2 f/ m) R; Uenum LockTypeEnum LockType, 6 }3 J% k! f% {3 y$ o$ g
long Options )
3 Q3 h0 k$ A: Q7 s# L, X, B( R3 q
- i* C1 W( L6 _. \, ]* O其中:
1 b' |; O: O3 {9 {+ [& l
$ l( q  T1 M% Q①Source是数据查询字符串; ^2 k' l0 E' s7 @
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象) ' R6 z7 \$ H. i' }. x4 l2 }  h
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:* G& K. n  ~  o- R

3 j' D" d; L8 ~enum CursorTypeEnum) f/ y+ }" Z, x; r1 f, [3 Y9 a  U0 U
{5 N* k+ N3 L$ E, [& l- p
adOpenUnspecified = -1,///不作特别指定
6 F# A. _/ o0 f+ ~2 yadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
; h' D+ _; A  n) k/ _7 b/ @adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。% K1 _8 _6 F2 o2 _
& ~8 d2 _, P$ y( X0 C4 T3 Q* a: f* p( \
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。% A" U) i1 v* K# _4 T
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
/ ~" p- m, L: \8 p' g};
3 J4 s# S7 j2 M$ h8 _④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:: \1 _) X+ z* n- V4 a9 \& f

0 D( q; o% c+ tenum LockTypeEnum$ d- N: f5 j8 b  m6 I  n+ ]
{
+ e2 V4 ]1 p& q2 |adLockUnspecified = -1,///未指定4 L7 M) H. Q9 o8 g1 L8 o) |7 U
adLockReadOnly = 1,///只读记录集
# f5 m0 C9 Z3 C5 ?adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
' e, Q: O7 ?" l4 J& o# a# T# f; \adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
+ P9 o; N2 d+ {. C6 |adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
* ~& B* d- O3 v5 W};
) r- Y; i$ P1 d, K+ X, i& U" M) n; j( {! _. y% J" o- Y
⑤Options可以取如下值之一:7 a0 n7 x& H+ z, y4 e
adCmdText:表明CommandText是文本命令
% g" B: F5 y- p9 f8 A  SadCmdTable:表明CommandText是一个表名
$ i  j3 A$ }! Q! Y3 \+ qadCmdProc:表明CommandText是一个存储过程- K0 D; E) {6 g1 A2 m. q' R0 q
adCmdUnknown:未知
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-18 20:48 , Processed in 0.421460 second(s), 52 queries .

回顶部