QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集
- V3 i% ], i! @+ O4 c3 Q. j$ V' l  }3 A" b: a! Z
  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
1 z  r' F2 y0 J- x9 d并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");. ?4 g4 E4 _- p) j, L/ O* a1 f
SQL命令的执行可以采用多种形式,下面我们一进行阐述。7 M5 p8 V' n' k" @4 Q
8 ~' ]8 V; q& X4 S, ~9 ?+ H
  (1)利用Connection对象的Execute方法执行SQL命令
. `. ^/ T  S/ k
; i" G5 C6 m: C5 L1 `  Execute方法的原型如下所示:
/ j3 \: o8 {- n; j8 v; G
# h! X2 f% p* k( f  J! ?2 ]_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) 6 p8 M  ^7 T5 N' A1 Z3 i3 C3 p$ O
+ D/ w# e" j' O6 ]; o
其中CommandText是命令字串,通常是SQL命令。3 Q. B) e* @' A, y! y
参数RecordsAffected是操作完成后所影响的行数,
$ P% h! w; s) b6 t4 Z7 m参数Options表示CommandText中内容的类型,Options可以取如下值之一:! i) B7 j6 r5 L9 b# U4 Z  F
adCmdText:表明CommandText是文本命令* @$ q  P, F* Y+ Y; Q% G
adCmdTable:表明CommandText是一个表名  ~3 s% k6 x! R
adCmdProc:表明CommandText是一个存储过程4 z: g, {" W4 Z' r
adCmdUnknown:未知$ g: z, j" @- N3 X, }
% l0 W  z+ B3 }/ Q
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。 # V8 `/ U; w+ B, I
_variant_t RecordsAffected;/ y; R5 |& }  p& k8 x; |
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
; \- H2 L: N& D  k) G0 W  }; Km_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
- r/ a$ j# g* T/ q/ ~1 T&RecordsAffected,
1 Z; K# Y+ ?& M1 Q: T/ VadCmdText);
+ [. F. n( v* J7 A% w: B5 `0 G6 `$ F; p
///往表格里面添加记录
( b7 Y, N! @8 V0 B* o- Y# Pm_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);4 A6 D+ p  y+ u- b; g5 a; J) `) }) O
% x, w) u( @& D  @+ J9 }/ m
///将所有记录old字段的值加一
, i; F( _: j" bm_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);' h2 x8 O5 a& q$ J8 ?, [" V3 ?
7 \, U  ]0 B4 D3 u
///执行SQL统计命令得到包含记录条数的记录集
6 ~6 r  s. c: V( D6 q4 Hm_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
' u4 I4 |2 H0 [' Z3 c' u1 _) i0 \_variant_t vIndex = (long)0;
, @5 Z- Z8 i: v$ ?_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量7 u' O. Y# ?- E8 e$ T: @2 m7 Q
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));9 y" @9 T1 o$ K5 S
m_pRecordset->Close();///关闭记录集' f/ ?7 v9 V3 m7 h# `5 Q( Z
CString message;2 ]* i9 {2 R: v: r/ A
message.format("共有%d条记录",vCount.lVal);' r5 L* C% _  H# M' r" d1 e
AfxMessageBox(message);///显示当前记录条数: n7 d: g$ O" \* w. x) G: H
5 ?8 p$ k% l: Q$ C$ G: ]
(2)利用Command对象来执行SQL命令
% q3 {& J. G6 J% x
/ P# K2 K2 Y; c5 B7 g, e# J5 f9 L_CommandPtr m_pCommand;) p8 w* \, t0 x5 N& E! G. m& Z
m_pCommand.CreateInstance("ADODB.Command");# d( w' L0 v% Z1 I' N" r. ]5 N
_variant_t vNULL;9 K4 \6 s! R8 s$ M- @
vNULL.vt = VT_ERROR;
4 u- e" F: P% J" i( s5 [5 \vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数9 Q( n! Y9 j$ U% f/ a9 B
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它- V+ l! F+ n$ `, R' \
m_pCommand->CommandText = "SELECT * FROM users";///命令字串+ B- ~( O. ?0 c2 C( Y
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
# H& Z4 H6 ^' V4 _( M# k( j& l+ G& Y+ C' k" R& J
  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。 ; d* J6 E0 t( t4 l- t; S* J6 T
' |" y+ D6 U7 \
  (3)直接用Recordset对象进行查询取得记录集
: ~7 k- d' L. d7 ], S) i, Z1 C
; N1 c3 q3 `9 ?/ N( p) a  实例——
6 ~" @# l3 A; {2 N6 r. [9 Y  @1 K; x- q7 a5 c0 q- B& @
void CGmsaDlg::OnDBSelect() 2 l* e' ~4 Y( L+ b, Z" Y! d; g
{
: X5 r, R. N! j// TOD Add your control notification handler code here/ a% @* _. V2 N7 L$ y5 E9 W
_RecordsetPtr Rs1; //定义Recordset对象2 b* H' b" V2 e# A1 B$ {( {
_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串# C. U, ~. o# n6 @* y$ z3 d
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
! K9 Z% }) b" M. N; q::CoInitialize(NULL); //初始化Rs1对象
" ]4 g" ]# D" V) H( n  l9 l9 THRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
  m1 ?$ V  J/ b9 n7 K) W//省略对返回值hr的判断
6 z7 {+ I) p0 J$ Q! NRs1->Open( Source,2 X( |  R; S3 b- N
Connect,% e/ c! K% c" q% a! ?3 U: }! ?# y
adOpenForwardOnly,
' Q/ L4 y2 R5 m! u0 gadLockReadOnly,: D! ?: U7 x8 a
-1 );
: D& y$ u- T. c_variant_t temp=Rs1->GetCollect(_variant_t((long)0));6 e2 o. Q# ?/ c9 n* v+ N3 U2 Z" V8 K& e" u
CString strTemp=(char* )(_bstr_t)temp;0 c# G( f+ r( j" ^. ^$ n# C0 [4 [" [
MessageBox("OK!"+strTemp);1 j# G9 t& Y* \5 W4 ^1 R5 j
}+ O' G4 o( m  i9 ?, C

" V( @6 W; o: q7 O" M: j例如 * V2 i/ `' J2 O7 c& a( }
m_pRecordset->Open("SELECT * FROM users",
3 o6 V! F* K/ i* p% q, o8 P& s3 z_variant_t((IDispatch *)m_pConnection,true),# I0 J( S; W$ w- y7 |
adOpenStatic,  k  X& H' K% s! w7 ~3 B" N
adLockOptimistic,, F: D% @2 B% e' M, l& O5 \% K" {% W
adCmdText);
5 @2 ~  t! d& B& D9 N
2 ]% G4 k* M1 lOpen方法的原型是这样的:, @$ u. K% }: i5 m
HRESULT Recordset15::Open ( const _variant_t & Source,
0 W" s4 t% Y7 M. w) Sconst _variant_t & ActiveConnection,
" w2 w; e+ L; Qenum CursorTypeEnum CursorType,
' y; J( B4 p1 k3 A' venum LockTypeEnum LockType, ( J- O4 t! c& k
long Options )
9 G) m6 S0 {+ }! P( Z: z9 D& e% {7 e4 s. v9 B
其中:
' i2 l, J& C) C8 I
( o2 A3 [" I9 u* ], N①Source是数据查询字符串
9 _/ s4 s1 n0 F' {1 G* D0 b) n②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
# Q7 @8 _9 n8 ~) |③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
$ Z" E. U5 }5 x) K1 w* d  c1 e6 ?1 c4 [0 S% L8 |! L7 ~# }# G/ ^
enum CursorTypeEnum, t6 I: ^5 U& C& D, {
{/ m7 J1 @4 l& S1 G4 ]+ x5 E( @: c
adOpenUnspecified = -1,///不作特别指定
6 Z6 J; L7 q9 ]2 K% z2 eadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
( H" }  y' j$ ]: o2 IadOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
, M% W. J8 r3 d- G: ], ?8 S+ t! }) V5 S# ~* k5 J) u
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。4 K& X( c3 I: |1 A2 A0 Q
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
2 P/ Y  n* U9 u; b* U# q, D};( u: F# K7 v( p
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
" v2 G4 S1 ]" w0 T; w" }- [  M
- c* k# g- T& H/ Venum LockTypeEnum5 Y. h: ^1 o, K/ w
{) M) G, }" X/ i2 {% P. S+ I
adLockUnspecified = -1,///未指定; {+ X6 ~6 D. n- Q3 m
adLockReadOnly = 1,///只读记录集
, q+ y9 v0 I% t" J, U" U4 s' EadLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
% [# Z/ Y+ h5 k# hadLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作! k$ v+ K! e9 S2 `# g3 |2 H5 N$ h
adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
' O! u. W+ @+ G5 ]}; : I2 R1 a( I8 `$ b; O8 e
" X3 B) t) B! q( Q: h
⑤Options可以取如下值之一:
3 N9 V8 x( q: H  F) P: eadCmdText:表明CommandText是文本命令
. C7 D7 b; R. r% hadCmdTable:表明CommandText是一个表名; X- r" ?# e# I0 Q! D) K; m! d$ |
adCmdProc:表明CommandText是一个存储过程/ s8 L' I  i0 d
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-17 06:18 , Processed in 0.410379 second(s), 51 queries .

回顶部